C ++ में, है ?: ऑपरेटर तेजी से अगर () ... और कथनों? संकलित कोड में उनके बीच कोई अंतर हैं?
if
अनुमति देता है जबकि बयान की अनुमति देता है।
C ++ में, है ?: ऑपरेटर तेजी से अगर () ... और कथनों? संकलित कोड में उनके बीच कोई अंतर हैं?
if
अनुमति देता है जबकि बयान की अनुमति देता है।
जवाबों:
आपके संकलक पर निर्भर करता है, लेकिन किसी भी आधुनिक संकलक पर आमतौर पर कोई अंतर नहीं होता है। यह कुछ ऐसा है जिसके बारे में आपको चिंता नहीं करनी चाहिए। अपने कोड की स्थिरता पर ध्यान केंद्रित करें।
यह तेज नहीं है। जब आप कुछ अभिव्यक्ति के आधार पर एक स्थिर चर को इनिशियलाइज़ कर सकते हैं तो एक अंतर होता है:
const int x = (a<b) ? b : a;
आप ऐसा नहीं कर सकते if-else
।
const
चर के साथ संभव नहीं है ।
max
? const int x = max(a,b);
ठीक काम करता है।
max ? const int x = max(a,b);
और सोचा था कि वाह! ये क्या डब्ल्यूटीएफ है! तो मैं इसे फिर से पढ़ा और देखा कि प्रश्न चिह्न मोनोस्पेस नहीं था! विषय दिया, मुझे लगता है कि मैं सोच में उचित था? कमान का हिस्सा था! :)
const int x = [&] -> int { if (a < b) return b; else return a; }
।
मैंने GCC को सशर्त ऑपरेटर को cmov
(सशर्त चाल) निर्देशों में बदलते हुए देखा है, जबकि if
शाखाओं में बयान देते हुए , जो हमारे मामले में मतलब था, सशर्त ऑपरेटर का उपयोग करते समय कोड तेज था। लेकिन यह कुछ साल पहले था, और आज की संभावना है, दोनों एक ही कोड के लिए संकलन करेंगे।
वहाँ कोई गारंटी नहीं है कि वे एक ही कोड के लिए संकलन करेंगे। यदि आपको प्रदर्शन की आवश्यकता है, तो हमेशा की तरह मापें । और जब आपने मापा और पता चला कि 1. आपका कोड बहुत धीमा है, और 2. यह कोड का यह विशेष हिस्सा है जो अपराधी है, तो कंपाइलर द्वारा उत्पन्न असेंबली कोड का अध्ययन करें और अपने लिए जांचें कि क्या हो रहा है।
अगर मैं सशर्त ऑपरेटर का उपयोग करता हूं, तो "संकलक हमेशा अधिक कुशल कोड उत्पन्न करेगा" जैसे सुनहरे नियमों पर भरोसा न करें।
Only one of the second and third expressions is evaluated. Every value computation and side effect associated with the first expression is sequenced before every value computation and side effect associated with the second or third expression.
कौन सा स्पष्ट रूप से संकलक को एक cmove
निर्देश उत्पन्न करने से रोकता है ।
वे समान हैं, हालांकि, टर्नरी ऑपरेटर का उपयोग उन जगहों पर किया जा सकता है जहां पर अगर / का उपयोग करना मुश्किल है:
printf("Total: %d item%s", cnt, cnt != 1 ? "s" : "");
अगर / के साथ वह कथन करना, एक बहुत अलग संकलित कोड उत्पन्न करेगा।
8 साल बाद अपडेट ...
वास्तव में, मुझे लगता है कि यह बेहतर होगा:
printf(cnt == 1 ? "Total: %d item" : "Total: %d items", cnt);
(वास्तव में, मुझे पूरा यकीन है कि आप "% d" को "एक" के साथ पहली स्ट्रिंग में बदल सकते हैं)
printf("Total: %d item%s", cnt, "s" + (cnt==1));
lpStrFilter
के लिए OPENFILENAME संरचनाओं का सदस्य )
%s
प्रिंट करता है, लेकिन \0
स्रोत स्ट्रिंग से शामिल नहीं है ।
printf("Total: %d item%s", cnt, "s" + (cnt==1));
काम करता है ?
(cnt==1)
सच या गलत है, जो 0 या 1 में परिवर्तित होता है। "s" एक नेल-टर्मिनेटेड स्ट्रिंग का सूचक है। एक अक्षर को जोड़कर एक अक्षर (एस)। तो यह प्रिंट या तो "s" या "" है।
बस थोड़ा सा बचे रहना है ...
x ? y : x = value
यदि x 0 नहीं है (तो) y को मान प्रदान करेगा ।
संकलित कोड के बावजूद, वे शब्दार्थ रूप से भिन्न हैं। <cond>?<true expr>:<false expr>
एक अभिव्यक्ति है और if..else..
एक बयान है।
हालांकि सशर्त अभिव्यक्ति का वाक्यविन्यास अजीब लगता है, यह एक अच्छी बात है। आपको एक प्रदान करने के लिए मजबूर किया जाता है <false expr>
और दो अभिव्यक्तियाँ टाइप की जाती हैं।
if..else..
लिस्प, हास्केल जैसी अभिव्यक्ति-आधारित, कार्यात्मक भाषा के बराबर है? :
के बजाय C ++ में, if..else..
बयान।
आप इसे एक पंक्ति में रखने के लिए मजबूर नहीं हैं: -
x = y==1 ?
2
:// else
3;
यह अगर / अन्यथा की तुलना में बहुत स्पष्ट है क्योंकि आप तुरंत देख सकते हैं कि दोनों शाखाओं को x को सौंपा जा रहा है।
मैं उम्मीद करूंगा कि अधिकांश संकलक और लक्ष्य प्लेटफार्मों पर, ऐसे मामले होंगे जहां "अगर" तेज है और जहां मामले ?: तेज है। ऐसे मामले भी होंगे जहां एक रूप दूसरे की तुलना में कम या अधिक कॉम्पैक्ट है। कौन से मामले एक रूप का पक्ष लेते हैं या दूसरे संकलक और प्लेटफार्मों के बीच अलग-अलग होंगे। यदि आप एम्बेडेड माइक्रो पर प्रदर्शन-महत्वपूर्ण कोड लिख रहे हैं, तो देखें कि प्रत्येक मामले में कंपाइलर क्या उत्पन्न कर रहा है और देखें कि कौन सा बेहतर है। एक "मुख्य धारा" पीसी पर, कैशिंग मुद्दों के कारण, यह देखने का एकमात्र तरीका है कि बेहतर है कि असली एप्लिकेशन से मिलता-जुलता दोनों रूपों में बेंचमार्क करें।
सीए टर्नेरी ऑपरेटर में ?: "" फॉर्म के सशर्त अभिव्यक्ति के निर्माण के लिए उपलब्ध है
exp1 ? exp2:exp3
जहां exp1, exp2 और exp3 अभिव्यक्ति हैं
उदाहरण के लिए
a=20;
b=25;
x=(a>b)?a:b;
in the above example x value will be assigned to b;
यह if..else स्टेटमेंट निम्नानुसार उपयोग करके लिखा जा सकता है
if (a>b)
x=a;
else
x=b;
** इसलिए इन दोनों में कोई अंतर नहीं है। यह प्रोग्रामर को आसानी से लिखने के लिए है, लेकिन कंपाइलर के लिए दोनों समान हैं। *
कुछ कोड उलटने के दौरान (जो मुझे याद नहीं है, कुछ साल पहले) मैंने मशीन कोड के बीच एकल लाइन अंतर देखा:? और अगर-और।
Don't remember much but it is clear that implementation of both is different.
लेकिन मैं आपको सलाह देता हूं कि आप उनमें से किसी एक को अपनी दक्षता के अनुसार न चुनें, कोड की पठनीयता या अपनी सुविधा के अनुसार चुनें। हैप्पी कोडिंग
टर्नेरी ऑपरेटर हमेशा एक मूल्य देता है। इसलिए ऐसी स्थिति में जब आप परिणाम से कुछ आउटपुट वैल्यू चाहते हैं और टर्नरी ऑपरेटर का उपयोग करने के लिए केवल 2 स्थितियां हमेशा बेहतर होती हैं। यदि उपर्युक्त शर्तों में से कोई भी सत्य नहीं है, तो अन्य का उपयोग करें।
मुझे लगता है कि ऐसे हालात हैं जहां अगर इनलाइन काम करती है तो इनलाइन "तेज" कोड प्राप्त कर सकती है। वस्तु निर्माण और विनाश महंगा हो सकता है इसलिए निम्नलिखित परिदृश्य पर विचार करें:
class A{
public:
A() : value(0) {
cout << "Default ctor" << endl;
}
A(int myInt) : value(myInt)
{
cout << "Overloaded ctor" << endl;
}
A& operator=(const A& other){
cout << "= operator" << endl;
value = other.value;
}
~A(){
cout << "destroyed" << std::endl;
}
int value;
};
int main()
{
{
A a;
if(true){
a = A(5);
}else{
a = A(10);
}
}
cout << "Next test" << endl;
{
A b = true? A(5) : A(10);
}
return 0;
}
इस कोड के साथ, आउटपुट होगा:
Default ctor
Overloaded ctor
= operator
destroyed
destroyed
Next test
Overloaded ctor
destroyed
इसलिए, यदि हम, तो हम एक a
ही दायरे में जिंदा रखने के लिए आवश्यक ऑपरेशन का एक गुच्छा बचा लेते हैं b
। हालांकि यह अत्यधिक संभावना है कि स्थिति मूल्यांकन की गति दोनों परिदृश्यों में बहुत समान है, बदलते गुंजाइश आपको अन्य कारकों को ध्यान में रखने के लिए मजबूर करते हैं कि इनलाइन अगर आपको बचने की अनुमति देती है।
A a(true ? 5 : 10);
अब मैं आपकी मदद नहीं कर सकता, मैं इसके नीचे एक द्वितीयक प्रश्न के साथ मदद करने में सक्षम हो सकता हूं, क्या मैं इसका उपयोग करना चाहता हूं? यदि आप केवल गति जानना चाहते हैं, तो बस मेरी टिप्पणी को अनदेखा करें।
सभी मैं कह सकता हूँ कि टर्नरी का उपयोग कब करना है? : ऑपरेटर। यह पठनीयता के लिए एक अभिशाप जितना आशीर्वाद हो सकता है।
अपने आप से पूछें कि क्या आपको इसे इस्तेमाल करने से पहले पढ़ना आसान लगता है
int x = x == 1 ? x = 1 : x = 1;
if (x == 1)
{
x = 1
}
else
{
x = 2
}
if (x == 1)
x = 1
else
x = 1
हां यह कोड को 100% फर्जी बनाने के लिए मूर्खतापूर्ण लगता है। लेकिन उस छोटी सी चाल ने मुझे कोड की अपनी पठनीयता का विश्लेषण करने में मदद की। यह उस नमूने में आपके द्वारा देखे जाने वाले ऑपरेटर की पठनीयता है, न कि सामग्री।
यह साफ-सुथरा रहता है, लेकिन औसत टॉयलेट सीट और डोरकनॉब
मेरे अनुभव में, जो सीमित है, मैंने देखा है कि बहुत कम लोग वास्तव में एक टर्नरी ऑपरेटर से आवश्यक जानकारी को जल्दी से प्रत्यर्पित करने में सक्षम होते हैं, जब तक कि यह 100% बेहतर न हो। जब मुझे लगता है कि यह खराब है, तो इसे ठीक करने के लिए एक दर्द है
int x = x == 1 ? 1 : 2
या संभवतःint x = (x == 1) ? 1 : 2
x = x = 1;
हर जगह क्यों नहीं लिखते हैं और फिर शिकायत करते हैं कि असाइनमेंट बहुत जटिल है और इसे टाला जाना चाहिए।