यहां उत्तरों में जोड़ने के लिए, मुझे लगता है कि यह इसके साथ संयोजन के रूप में विपरीत प्रश्न पर विचार करने के लायक है, अर्थात। C ने पहले स्थान पर गिरने की अनुमति क्यों दी?
किसी भी प्रोग्रामिंग भाषा में दो लक्ष्य होते हैं:
- कंप्यूटर को निर्देश प्रदान करें।
- प्रोग्रामर के इरादों का एक रिकॉर्ड छोड़ दें।
इसलिए किसी भी प्रोग्रामिंग भाषा का निर्माण इन दो लक्ष्यों को सर्वोत्तम तरीके से पूरा करने के बीच एक संतुलन है। एक तरफ, कंप्यूटर निर्देशों में बदलना आसान है (चाहे वे मशीन कोड हों, आईएल जैसे बायटेकोड, या निष्पादन पर निर्देशों की व्याख्या की जाती है) फिर अधिक सक्षम संकलन या व्याख्या की प्रक्रिया कुशल, विश्वसनीय और होगी आउटपुट में कॉम्पैक्ट। अपनी चरम सीमा तक, यह लक्ष्य हमारे विधानसभा, आईएल या यहां तक कि कच्चे ऑप-कोड में लिखने का परिणाम है, क्योंकि सबसे आसान संकलन वह है जहां कोई संकलन नहीं है।
इसके विपरीत, भाषा जितनी अधिक प्रोग्रामर के इरादे को व्यक्त करती है, उस अंत तक ले जाने वाले साधनों की बजाय, लिखने और रखरखाव के दौरान कार्यक्रम को समझने में उतना ही अधिक समझ में आता है।
अब, switch
हमेशा इसे if-else
ब्लॉकों या समान के बराबर श्रृंखला में परिवर्तित करके संकलित किया जा सकता था, लेकिन इसे एक विशेष आम विधानसभा पैटर्न में संकलन की अनुमति के रूप में डिज़ाइन किया गया था, जहां कोई मान लेता है, उससे एक ऑफसेट गणना करता है (चाहे एक तालिका देख कर। मूल्य के एक आदर्श हैश द्वारा अनुक्रमित, या मूल्य पर वास्तविक अंकगणित द्वारा *)। यह इस बिंदु पर ध्यान देने योग्य है कि आज, सी # संकलन कभी-कभी switch
समकक्ष में बदल जाएगा if-else
, और कभी-कभी हैश-आधारित कूद दृष्टिकोण का उपयोग करें (और इसी तरह सी, सी ++, और तुलनीय वाक्यविन्यास के साथ अन्य भाषाओं में)।
इस मामले में गिरावट की अनुमति देने के दो अच्छे कारण हैं:
यह वैसे भी स्वाभाविक रूप से होता है: यदि आप निर्देशों के एक सेट में एक जंप टेबल का निर्माण करते हैं, और निर्देशों के पहले बैचों में किसी प्रकार का कूद या रिटर्न नहीं होता है, तो निष्पादन अगले बैच में स्वाभाविक रूप से प्रगति करेगा। यदि आप switch
-यूज़िंग सी को जंप-टेबल-मशीन मशीन के उपयोग से चालू करते हैं, तो गिरने के माध्यम से अनुमति देना "क्या होगा" ।
असेंबली में लिखने वाले कोडर्स पहले से ही समतुल्य थे: जब असेंबली में हाथ से एक जंप टेबल लिखते हैं, तो उन्हें इस पर विचार करना होगा कि क्या कोड का दिया गया ब्लॉक रिटर्न के साथ समाप्त होगा, टेबल के बाहर कूद, या बस जारी रहेगा अगले ब्लॉक के लिए। जैसे, break
जब आवश्यक हो तो कोडर को स्पष्ट रूप से जोड़ना "कोडर के लिए" स्वाभाविक था।
इसलिए उस समय, यह एक कंप्यूटर भाषा के दो लक्ष्यों को संतुलित करने का एक उचित प्रयास था क्योंकि यह उत्पादित मशीन कोड और स्रोत कोड की अभिव्यंजना दोनों से संबंधित है।
चार दशक बाद हालांकि, कुछ कारणों से चीजें समान नहीं हैं:
- C में कोडर्स का आज कम या कोई असेंबली अनुभव नहीं हो सकता है। कई अन्य सी-शैली भाषाओं में कोडर भी (विशेष रूप से जावास्क्रिप्ट!) की संभावना कम है। "असेंबली से लोगों का क्या उपयोग किया जाता है" की कोई भी अवधारणा अब प्रासंगिक नहीं है।
- ऑप्टिमाइज़ेशन में सुधार का अर्थ है कि
switch
या तो होने की संभावनाif-else
क्योंकि इसे दृष्टिकोण को सबसे अधिक कुशल माना जाता था, या फिर जंप-टेबल दृष्टिकोण के विशेष रूप से गूढ़ रूप में बदल दिया जाता है। उच्च और निचले स्तर के दृष्टिकोणों के बीच मानचित्रण उतना मजबूत नहीं है जितना एक बार था।
- अनुभव से पता चला है कि फॉल-थ्रू के बजाय मानक के बजाय अल्पसंख्यक का मामला है (सूर्य के संकलक के एक अध्ययन में पाया गया कि 3%
switch
ब्लॉकों ने एक ही ब्लॉक पर कई लेबल के अलावा अन्य फ़ॉल-थ्रू का उपयोग किया था, और यह सोचा गया था कि उपयोग- यहां केस का मतलब है कि यह 3% वास्तव में सामान्य से बहुत अधिक था)। इसलिए अध्ययन की गई भाषा आम की तुलना में असामान्य रूप से अधिक आसानी से कैटरिंग-इन बनाती है।
- अनुभव ने दिखाया है कि फॉल-थ्रू उन मामलों में दोनों समस्याओं का स्रोत बन जाता है जहां यह गलती से किया जाता है, और उन मामलों में भी जहां सही फॉल-थ्रू किसी को कोड बनाए रखने से चूक जाता है। यह उत्तरार्द्ध फॉल-थ्रू से जुड़े बग के लिए एक सूक्ष्म अतिरिक्त है, क्योंकि भले ही आपका कोड पूरी तरह से बग-मुक्त हो, फिर भी आपका फ़ॉल-थ्रू समस्या पैदा कर सकता है।
उन अंतिम दो बिंदुओं से संबंधित, K & R के वर्तमान संस्करण के निम्नलिखित उद्धरण पर विचार करें:
एक मामले से दूसरे में गिरना मजबूत नहीं है, जब कार्यक्रम को संशोधित किया जाता है तो विघटन होने का खतरा होता है। एक एकल संगणना के लिए कई लेबल के अपवाद के साथ, फॉल-थ्रू को संयम से इस्तेमाल किया जाना चाहिए, और टिप्पणी की जानी चाहिए।
अच्छे रूप के रूप में, अंतिम मामले (यहां डिफ़ॉल्ट) के बाद भी एक ब्रेक लगा दें, भले ही यह तार्किक रूप से अनावश्यक हो। किसी दिन जब अंत में एक और मामला जुड़ जाता है, तो रक्षात्मक प्रोग्रामिंग का यह बिट आपको बचाएगा।
तो, घोड़े के मुंह से, सी में गिरना समस्याग्रस्त है। इसे हमेशा टिप्पणियों के साथ गिरने वाले दस्तावेज़ों के लिए अच्छा अभ्यास माना जाता है, जो सामान्य सिद्धांत का एक अनुप्रयोग है कि व्यक्ति को दस्तावेज़ करना चाहिए जहां कोई असामान्य चीज़ करता है, क्योंकि यही वह है जो कोड की बाद की परीक्षा की यात्रा करेगा और / या अपना कोड जैसा बना देगा यह वास्तव में सही है, जब इसमें एक नौसिखिया बग है।
और जब आप इसके बारे में सोचते हैं, तो कोड इस तरह होता है:
switch(x)
{
case 1:
foo();
/* FALLTHRU */
case 2:
bar();
break;
}
है कुछ जोड़ने गिरावट के माध्यम से कोड में स्पष्ट बनाने के लिए, यह सिर्फ कुछ है कि पता लगाया जा सकता है (या जिसका अभाव पाया जा सकता है) संकलक द्वारा नहीं है।
इस प्रकार, इस तथ्य पर कि C # में फॉल-थ्रू के साथ स्पष्ट होना पड़ता है, वैसे लोगों के लिए कोई जुर्माना नहीं जोड़ता है जो अन्य सी-शैली की भाषाओं में अच्छी तरह से लिखते हैं, क्योंकि वे पहले से ही अपने पतन के माध्यम से स्पष्ट होंगे।
अंत में, goto
यहाँ का उपयोग पहले से ही C और ऐसी अन्य भाषाओं से एक आदर्श है:
switch(x)
{
case 0:
case 1:
case 2:
foo();
goto below_six;
case 3:
bar();
goto below_six;
case 4:
baz();
/* FALLTHRU */
case 5:
below_six:
qux();
break;
default:
quux();
}
इस तरह के मामले में जहां हम चाहते हैं कि एक ब्लॉक को कोड में शामिल किया जाना चाहिए, जो केवल एक मूल्य के अलावा किसी अन्य को शामिल करता है, जो पूर्ववर्ती ब्लॉक में लाता है, तो हम पहले से ही उपयोग कर रहे हैं goto
। (बेशक, अलग-अलग सशर्त के साथ इससे बचने के साधन और तरीके हैं लेकिन यह इस सवाल से संबंधित हर चीज के बारे में सच है)। जैसे कि C # एक स्थिति से निपटने के लिए पहले से ही सामान्य तरीके से बनाया गया है, जहाँ हम कोड के एक से अधिक ब्लॉक को हिट करना चाहते हैं switch
, और साथ ही इसे फॉल-थ्रू कवर करने के लिए सामान्यीकृत किया है। इसने दोनों मामलों को और अधिक सुविधाजनक और स्व-दस्तावेजीकरण बना दिया, क्योंकि हमें C में एक नया लेबल जोड़ना है, लेकिन case
C # में लेबल के रूप में उपयोग कर सकते हैं । C # में हम below_six
लेबल से छुटकारा पा सकते हैं और उपयोग कर सकते हैं goto case 5
जो कि स्पष्ट है कि हम क्या कर रहे हैं। (हमें भी जोड़ना होगाbreak
उसके लिए default
, जिसे मैंने उपरोक्त C कोड स्पष्ट रूप से C # कोड नहीं बनाने के लिए छोड़ा था)।
इसलिए संक्षेप में:
- C # अब 40 वर्ष पहले (न ही C इन दिनों में) C कोड के रूप में सीधे अनियंत्रित संकलक आउटपुट से संबंधित है, जो कि अप्रासंगिक के पतन के प्रेरणाओं में से एक बनाता है।
- C #
break
समान भाषाओं से परिचित लोगों द्वारा भाषा को आसानी से सीखने, और आसान पोर्टिंग करने के लिए C का अर्थ निहित नहीं है ।
- सी # पिछले चार दशकों से समस्याओं के कारण के रूप में अच्छी तरह से प्रलेखित कीड़े या गलत कोड के संभावित स्रोत को हटाता है।
- C # कंपाइलर द्वारा लागू करने योग्य C (डॉक्युमेंट फॉल) के साथ मौजूदा बेस्ट-प्रैक्टिस करता है।
- C # असामान्य मामले को अधिक स्पष्ट कोड के साथ बनाता है, सामान्य केस कोड के साथ एक स्वचालित रूप से लिखता है।
- C #
goto
समान case
लेबल से एक ही ब्लॉक को हिट करने के लिए एक ही- आधारित दृष्टिकोण का उपयोग करता है जैसा कि C में उपयोग किया जाता है। यह इसे कुछ अन्य मामलों में सामान्य करता है।
- C # लेबल के रूप में कार्य करने की
goto
अनुमति देकर C की तुलना में उस- आधारित दृष्टिकोण को अधिक सुविधाजनक और स्पष्ट बनाता है case
।
सब सब में, एक बहुत ही उचित डिजाइन निर्णय
* BASIC के कुछ रूपों में से एक को GOTO (x AND 7) * 50 + 240
भंगुर करते समय पसंद करने की अनुमति दी जा सकती है और इसलिए प्रतिबंध लगाने के लिए एक विशेष रूप से प्रेरक मामला है goto
, जो उच्च-स्तरीय कोड के बराबर उच्च-भाषा दिखाने के लिए काम करता है जो निम्न-स्तरीय कोड के आधार पर एक छलांग लगा सकता है। एक मूल्य पर अंकगणित, जो कि अधिक उचित है जब यह संकलन के परिणाम के बजाय कुछ है जो मैन्युअल रूप से बनाए रखा जाना है। विशेष रूप से डफ़ डिवाइस के कार्यान्वयन खुद को बराबर मशीन कोड या आईएल के लिए अच्छी तरह से उधार देते हैं क्योंकि निर्देशों के प्रत्येक ब्लॉक को अक्सर nop
भराव के अतिरिक्त की आवश्यकता के बिना एक ही लंबाई होगी ।
A डफ का उपकरण एक उचित अपवाद के रूप में फिर से यहां आता है। तथ्य यह है कि उस और इसी तरह के पैटर्न के साथ ऑपरेशन का दोहराव उस प्रभाव के लिए एक स्पष्ट टिप्पणी के बिना भी गिरने के माध्यम से अपेक्षाकृत स्पष्ट उपयोग करने का कार्य करता है।