[रिकॉर्ड के लिए, मैंने इस उत्तर को काफी महत्वपूर्ण रूप से संपादित किया है क्योंकि इसे स्वीकार किया गया था और इस पर मतदान किया गया था। यह अभी भी मूल रूप से वही बातें कहता है, हालांकि।]
यह कोड गहरा है, शायद जानबूझकर, भ्रमित करने वाला। इसमें खूंखार अपरिभाषित व्यवहार का एक संकीर्ण-औसत उदाहरण है । यह निर्धारित करना मूल रूप से असंभव है कि जिस व्यक्ति ने इस प्रश्न का निर्माण किया था वह बहुत, बहुत चालाक या बहुत, बहुत बेवकूफ था। और "सबक" यह कोड आपको सिखाने या प्रश्नोत्तरी करने के लिए अनुमति दे सकता है - अर्थात्, कि संयुक्त प्लस ऑपरेटर बहुत कुछ नहीं करता है - निश्चित रूप से इस तरह के विध्वंसक गलत काम के लायक एक महत्वपूर्ण पर्याप्त नहीं है।
कोड के दो भ्रामक पहलू हैं, अजीब स्थिति:
while(+(+k--)!=0)
और यह नियंत्रित नियंत्रण कथन:
k=k++;
मैं पहले भाग को कवर करने जा रहा हूं।
यदि आपके पास एक चर है जैसे kआप 1 से बढ़ाना चाहते हैं, तो सी आपको एक नहीं, दो नहीं, तीन नहीं, बल्कि इसे करने के चार अलग-अलग तरीके देता है:
k = k + 1
k += 1
++k
k++
इस इनाम के बावजूद (या शायद इसकी वजह से), कुछ प्रोग्रामर भ्रमित हो जाते हैं और गर्भनिरोध जैसे खांसी करते हैं
k = k++;
यदि आप यह पता नहीं लगा सकते हैं कि यह क्या करना है, तो चिंता न करें: कोई भी नहीं कर सकता है। इस अभिव्यक्ति में k's मान ( k =भाग, और k++भाग) को बदलने के दो अलग-अलग प्रयास शामिल हैं , और क्योंकि C में कोई नियम नहीं है जो यह कहता है कि कौन से प्रयास "जीत" हुए हैं, इस तरह का एक अभिव्यक्ति औपचारिक रूप से अपरिभाषित है , जिसका अर्थ केवल इतना ही नहीं है इसका कोई अर्थ नहीं है, लेकिन इसका पूरा कार्यक्रम संदिग्ध है।
अब, यदि आप बहुत ध्यान से देखते हैं, तो आप देखेंगे कि इस विशेष कार्यक्रम में, लाइन k = k++वास्तव में निष्पादित नहीं होती है, क्योंकि (जैसा कि हम देखने वाले हैं) नियंत्रित स्थिति शुरू में झूठी है, इसलिए लूप 0 बार चलता है । इसलिए यह विशेष कार्यक्रम वास्तव में अपरिभाषित नहीं हो सकता है - लेकिन यह अभी भी विकृतिपूर्ण है।
इस तरह के अपरिभाषित व्यवहार के विषय में सभी प्रश्नों के उत्तर भी देखें ।
लेकिन आपने k=k++भाग के बारे में नहीं पूछा । आपने पहले भ्रमित करने वाले भाग, +(+k--)!=0स्थिति के बारे में पूछा । यह अजीब लग रहा है, क्योंकि यह है अजीब। कोई भी कभी भी, वास्तविक कार्यक्रम में ऐसा कोड नहीं लिखेगा। इसलिए इसे समझने का कोई कारण नहीं है। (हां, इसकी सही, एक प्रणाली की सीमाओं की खोज आपको इसके ठीक बिंदुओं के बारे में जानने में मदद कर सकती है, लेकिन मेरी किताब में कल्पनाशील, विचार-विहीन अन्वेषण बनाम गंदे, अपमानजनक अन्वेषणों के बीच एक स्पष्ट रेखा है, और यह अभिव्यक्ति बहुत स्पष्ट रूप से है उस लाइन का गलत पक्ष।)
वैसे भी, चलो जांच करते हैं +(+k--)!=0। (और ऐसा करने के बाद, चलो इसके बारे में सब भूल जाते हैं।) इस तरह की किसी भी अभिव्यक्ति को अंदर से बाहर समझना होगा। मुझे लगता है आप जानते हैं कि क्या
k--
कर देता है। यह kवर्तमान मूल्य लेता है और इसे बाकी की अभिव्यक्ति में "वापस" करता है, और यह कम या ज्यादा एक साथ घटता है k, यानी यह मात्रा को k-1वापस स्टोर करता है k।
लेकिन फिर क्या करता +है? यह एकात्मक प्लस है, न कि बाइनरी प्लस। यह सिर्फ एक शून्य के समान है। आप जानते हैं कि बाइनरी माइनस घटाव: अभिव्यक्ति है
a - b
एक से घटाव b। और आप जानते हैं कि एकात्मक ऋण चीजों को नकारता है: अभिव्यक्ति
-a
आपको एक का नकारात्मक देता है। क्या एकता +है ... मूल रूप से कुछ भी नहीं है। सकारात्मक मूल्यों को सकारात्मक और नकारात्मक मूल्यों को नकारात्मक में बदलने के बाद +aआपको aमूल्य देता है । तो अभिव्यक्ति
+k--
आपको जो कुछ भी k--दिया है, वह आपको देता है , जो कि kपुराना है।
लेकिन हम नहीं कर रहे हैं, क्योंकि हमारे पास है
+(+k--)
यह बस +k--आपको जो कुछ भी दिया गया है, उसे लेता है और +फिर से इस पर लागू होता है । तो यह आपको वह देता है जो आपने +k--दिया था, जो कुछ भी k--आपको दिया था, जो kपुराना था ।
तो अंत में, हालत
while(+(+k--)!=0)
बिल्कुल वैसा ही काम करता है जैसा कि बहुत अधिक सामान्य स्थिति में होता है
while(k-- != 0)
किया होता। (यह वही काम भी करता है जो और भी जटिल-सी दिखने वाली स्थिति while(+(+(+(+k--)))!=0)ने किया होगा। और वे कोष्ठक वास्तव में आवश्यक नहीं हैं; यह भी वही काम करता है while(+ + + +k--!=0)जो उसने किया होगा।)
यहां तक कि यह पता लगाना कि "सामान्य" स्थिति क्या है
while(k-- != 0)
है एक तरह से मुश्किल। इस लूप में दो चीजें चल रही हैं: जैसा कि लूप संभावित रूप से कई बार चलता है, हम इस पर जा रहे हैं:
- छोटे और छोटे
k--बनाने के लिए k, लेकिन यह भी करते रहें
- जो भी करता है, पाश के शरीर को करते रहो।
लेकिन हम इस k--भाग को तुरंत (पहले की प्रक्रिया में) तय करते हैं कि लूप के माध्यम से दूसरी यात्रा करना है या नहीं। और याद रखें कि k--"रिटर्न" पुराने मूल्य का k, इसे घटाने से पहले। इस कार्यक्रम में, का प्रारंभिक मान k0. है। इसलिए k--पुराने मान 0 को "वापस" करने जा रहा है, फिर k-1 पर अपडेट करें। लेकिन फिर बाकी हालत यह है != 0- लेकिन जैसा कि हमने अभी देखा, पहली बार जब हमने स्थिति का परीक्षण किया, तो हमें एक 0. मिला। इसलिए हम लूप के माध्यम से कोई यात्रा नहीं करेंगे, इसलिए हम इसे निष्पादित करने का प्रयास नहीं करेंगे समस्यात्मक बयान k=k++।
दूसरे शब्दों में, इस विशेष लूप में, हालांकि मैंने कहा कि "दो तरह की चीजें चल रही हैं", यह पता चला है कि 1 चीज एक बार होती है, लेकिन 2 चीज शून्य बार होती है।
किसी भी दर पर, मुझे उम्मीद है कि अब यह पर्याप्त रूप से स्पष्ट है कि किसी कार्यक्रम के लिए यह खराब बहाना मुद्रण -1 के अंतिम मूल्य के रूप में क्यों समाप्त होता है k। आम तौर पर, मुझे इस तरह के क्विज़ प्रश्नों का उत्तर देना पसंद नहीं है - यह धोखा देने जैसा लगता है - लेकिन इस मामले में, चूंकि मैं व्यायाम के पूरे बिंदु से बहुत अधिक असहमत हूं, इसलिए मुझे कोई आपत्ति नहीं है।