सी में सरणी आरंभीकरण के बारे में भ्रम


102

सी भाषा में, यदि इस तरह से एक सरणी इनिशियलाइज़ करें:

int a[5] = {1,2};

फिर सरणी के सभी तत्व जो प्रारंभिक रूप से स्पष्ट नहीं किए गए हैं, प्रारंभिक रूप से शून्य के साथ शुरू किए जाएंगे।

लेकिन, अगर मैं इस तरह से एक सरणी इनिशियलाइज़ करूँ:

int a[5]={a[2]=1};

printf("%d %d %d %d %d\n", a[0], a[1],a[2], a[3], a[4]);

उत्पादन:

1 0 1 0 0

मुझे समझ में नहीं आता, इसके बजाय a[0]प्रिंट क्यों करता 1है 0? क्या यह अपरिभाषित व्यवहार है?

नोट: यह प्रश्न एक साक्षात्कार में पूछा गया था।


35
अभिव्यक्ति का a[2]=1मूल्यांकन करता है 1
tkausl

14
एक बहुत गहरा सवाल। मुझे आश्चर्य है कि अगर साक्षात्कारकर्ता खुद जवाब जानता है। मैं नही। वास्तव में अभिव्यक्ति a[2] = 1का मूल्य सामान्य रूप से है 1, लेकिन मुझे यकीन नहीं है कि यदि आपको पहले तत्व के मूल्य के रूप में नामित प्रारंभिक अभिव्यक्ति का परिणाम लेने की अनुमति है। तथ्य यह है कि आपने वकील टैग जोड़ा है, मेरा मतलब है कि हमें मानक का हवाला देते हुए जवाब चाहिए।
बाथशीबा

15
खैर अगर यह उनका पसंदीदा सवाल है, तो आप अच्छी तरह से बुलेट को चकमा दे सकते हैं। व्यक्तिगत रूप से मैं एक लिखित प्रोग्रामिंग अभ्यास (एक कंपाइलर और डीबगर तक पहुंच के साथ) को पसंद करता हूं जो उपरोक्त जैसे "इक्का" शैली के प्रश्नों के बजाय कुछ घंटों में लिया जाता है। मैं कर सकता conject एक जवाब है, लेकिन मुझे नहीं लगता कि यह किसी भी असली तथ्यात्मक आधार होता है।
बाथशीबा

1
@ बाथशेबा मैं इसके विपरीत होगा, क्योंकि यहाँ जवाब अब दोनों सवालों के जवाब देता है।
गुडबाय एसई

1
@ बाथशीबा सबसे अच्छा होगा। फिर भी मैं ओपी को सवाल का श्रेय दूंगा, क्योंकि वह विषय के साथ आया था। लेकिन यह मेरे लिए तय करने के लिए नहीं है कि मुझे क्या लगता है "सही बात" होगी।
गुडबाय एसई

जवाबों:


95

TL; DR: मुझे नहीं लगता कि व्यवहार int a[5]={a[2]=1};को अच्छी तरह से परिभाषित किया गया है, कम से कम C99 में।

मज़ेदार हिस्सा यह है कि केवल बिट जो मेरे लिए समझ में आता है वह वह हिस्सा है जिसके बारे में आप पूछ रहे हैं: a[0]यह निर्धारित किया गया है 1क्योंकि असाइनमेंट ऑपरेटर उस मान को लौटाता है जो असाइन किया गया था। यह सब कुछ है जो अस्पष्ट है।

यदि कोड int a[5] = { [2] = 1 }होता है, तो सब कुछ आसान हो जाता है: यह एक निर्दिष्ट शुरुआती सेटिंग a[2]है 1और बाकी सब कुछ 0। लेकिन { a[2] = 1 }हमारे पास असाइनमेंट एक्सप्रेशन वाला एक गैर-नामित इनिशलाइज़र है, और हम एक खरगोश छेद नीचे गिरते हैं।


यहाँ मैंने अभी तक क्या पाया है:

  • a स्थानीय चर होना चाहिए।

    6.7.8 प्रारंभिक

    1. किसी ऑब्जेक्ट के लिए इनिशियलाइज़र के सभी भाव जिसमें स्थिर भंडारण अवधि होती है, स्थिर अभिव्यक्ति या स्ट्रिंग शाब्दिक होगा।

    a[2] = 1एक स्थिर अभिव्यक्ति नहीं है, इसलिए aस्वचालित भंडारण होना चाहिए।

  • a अपने स्वयं के प्रारंभ में गुंजाइश है।

    6.2.1 पहचानकर्ताओं के स्कोप

    1. संरचना, संघ और गणना टैग में गुंजाइश होती है जो टैग को घोषित करने वाले टाइप स्पेसियर में टैग की उपस्थिति के ठीक बाद शुरू होती है। प्रत्येक एन्यूमरेशन स्थिरांक में वह गुंजाइश होती है जो किसी एन्यूमरेटर सूची में अपने परिभाषित एन्यूमरेटर की उपस्थिति के ठीक बाद शुरू होती है। किसी अन्य पहचानकर्ता के पास वह गुंजाइश है जो उसके घोषणाकर्ता के पूरा होने के ठीक बाद शुरू होती है।

    घोषणाकर्ता है a[5], इसलिए वैरिएबल अपने स्वयं के प्रारंभ में दायरे में हैं।

  • a अपने स्वयं के प्रारंभ में जीवित है।

    6.2.4 वस्तुओं का भंडारण अवधि

    1. एक वस्तु जिसका पहचानकर्ता कोई संबंध के साथ और भंडारण-वर्ग विनिर्देशन के बिना घोषित किया जाता है staticहै स्वत: भंडारण अवधि

    2. ऐसी वस्तु जिसके लिए एक चर लंबाई सरणी प्रकार नहीं है, उसका जीवनकाल उस ब्लॉक में प्रवेश से फैलता है जिसके साथ यह जुड़ा हुआ है जब तक कि किसी भी तरह से उस ब्लॉक का निष्पादन समाप्त नहीं हो जाता। (एक संलग्न ब्लॉक में प्रवेश करना या किसी फ़ंक्शन को कॉल करना निलंबित करता है, लेकिन समाप्त नहीं होता है, वर्तमान ब्लॉक का निष्पादन।) यदि ब्लॉक को पुनरावर्ती रूप से दर्ज किया जाता है, तो प्रत्येक बार ऑब्जेक्ट का एक नया उदाहरण बनाया जाता है। वस्तु का प्रारंभिक मूल्य अनिश्चित है। यदि ऑब्जेक्ट के लिए एक इनिशियलाइज़ेशन निर्दिष्ट किया जाता है, तो इसे हर बार प्रदर्शन किया जाता है जब घोषणा ब्लॉक के निष्पादन में पहुंच जाती है; अन्यथा, मूल्य हर बार घोषित होने पर अनिश्चित हो जाता है।

  • के बाद एक अनुक्रम बिंदु है a[2]=1

    6.8 विवरण और ब्लॉक

    1. एक पूर्ण अभिव्यक्ति एक अभिव्यक्ति है जो किसी अन्य अभिव्यक्ति या एक घोषणाकर्ता का हिस्सा नहीं है। निम्नलिखित में से प्रत्येक एक पूर्ण अभिव्यक्ति है: एक इनिशियलाइज़र ; एक अभिव्यक्ति बयान में अभिव्यक्ति; चयन कथन ( ifया switch) की नियंत्रित अभिव्यक्ति ; एक whileया doबयान की नियंत्रण अभिव्यक्ति ; forकथन के प्रत्येक (वैकल्पिक) भाव ; एक returnबयान में (वैकल्पिक) अभिव्यक्ति । पूर्ण अभिव्यक्ति का अंत एक अनुक्रम बिंदु है।

    ध्यान दें कि में जैसे हिस्सा initializers की एक ब्रेस संलग्न सूची, जिनमें से प्रत्येक के बाद एक दृश्य बिंदु है।int foo[] = { 1, 2, 3 }{ 1, 2, 3 }

  • प्रारंभिक सूची क्रम में प्रारंभिक प्रदर्शन किया जाता है।

    6.7.8 प्रारंभिक

    1. प्रत्येक ब्रेस-एनक्लोज़र इनिशियलाइज़र सूची में एक संबद्ध करंट ऑब्जेक्ट होता है । जब कोई पदनाम मौजूद नहीं होता है, तो वर्तमान वस्तु के प्रकार के अनुसार वर्तमान वस्तु के उप-खंडों को आरंभ किया जाता है: उप-क्रम में सरणी तत्व, घोषणा क्रम में संरचना सदस्य, और संघ के पहले नामित सदस्य। [...]

     

    1. इनिशियलाइज़र सूची क्रम में हो सकता है, प्रत्येक इनिशियलाइज़र किसी विशेष सबबॉजेक्ट के लिए प्रदान किया जाता है जो उसी सब -जेक्ट के लिए किसी भी पहले सूचीबद्ध इनिशियलाइज़र को ओवरराइड करता है; स्पष्ट रूप से प्रारंभ नहीं किए गए सभी उप-ऑब्जेक्ट्स को प्रारंभिक रूप से समान रूप से समान किया जाएगा, जिसमें स्थिर भंडारण अवधि है।
  • हालांकि, प्रारंभिक अभिव्यक्तियों का क्रम में मूल्यांकन आवश्यक नहीं है।

    6.7.8 प्रारंभिक

    1. वह क्रम जिसमें आरम्भिक सूची के भावों के बीच कोई दुष्प्रभाव होता है, अनिर्दिष्ट है।

हालाँकि, अभी भी कुछ प्रश्न अनुत्तरित हैं:

  • अनुक्रम बिंदु भी प्रासंगिक हैं? मूल नियम है:

    6.5 भाव

    1. पिछले और अगले अनुक्रम बिंदु के बीच एक वस्तु का एक अभिव्यक्ति के मूल्यांकन के द्वारा एक बार में इसका संग्रहित मूल्य संशोधित होगा । इसके अलावा, स्टोर किए जाने वाले मूल्य को निर्धारित करने के लिए पूर्व मूल्य केवल पढ़ा जाएगा।

    a[2] = 1 एक अभिव्यक्ति है, लेकिन आरंभीकरण नहीं है।

    यह अनुबंध जे द्वारा थोड़ा विरोधाभास है:

    J.2 अपरिभाषित व्यवहार

    • दो अनुक्रम बिंदुओं के बीच, एक वस्तु को एक से अधिक बार संशोधित किया जाता है, या संशोधित किया जाता है और संग्रहीत मूल्य (6.5) निर्धारित करने के अलावा पूर्व मूल्य को पढ़ा जाता है।

    एनेक्स जे कहते हैं कि कोई भी संशोधन मायने रखता है, न कि केवल अभिव्यक्ति द्वारा संशोधन। लेकिन यह देखते हुए कि एनेक्स गैर-आदर्श हैं, हम शायद इसे अनदेखा कर सकते हैं।

  • आरंभिक अभिव्यक्तियों के संबंध में सबोबिज इनिशियलाइज़ेशन को किस प्रकार अनुक्रमित किया जाता है? क्या सभी इनिशियलाइज़र का पहले (किसी क्रम में) मूल्यांकन किया जाता है, फिर सबबॉजेक्ट्स को इनिशियलाइज़ किया जाता है (इनिशियल लिस्ट ऑर्डर में)? या उन्हें इंटरलेव किया जा सकता है?


मुझे लगता int a[5] = { a[2] = 1 }है कि इस प्रकार निष्पादित किया जाता है:

  1. aजब इसके ब्लॉक में प्रवेश किया जाता है, तो इसके लिए भंडारण आवंटित किया जाता है। इस बिंदु पर सामग्री अनिश्चित है।
  2. (केवल) इनिशियलाइज़र को निष्पादित a[2] = 1किया जाता है ( ), उसके बाद एक अनुक्रम बिंदु। यह स्टोर करता 1है a[2]और लौटता है 1
  3. इसका 1उपयोग इनिशियलाइज़ करने के लिए किया जाता है a[0](पहला इनिलाइज़र पहले सबोबिज को इनिशियलाइज़ करता है)।

लेकिन यहाँ बातें फजी क्योंकि शेष तत्वों (मिल a[1], a[2], a[3], a[4]) के लिए शुरू किए जाने की अपेक्षा की जाती है 0, लेकिन यह स्पष्ट नहीं है जब: यह पहले होता है a[2] = 1मूल्यांकन किया जाता है? यदि ऐसा है, a[2] = 1तो "जीत" और अधिलेखित हो जाएगा a[2], लेकिन क्या उस असाइनमेंट में अपरिभाषित व्यवहार होगा क्योंकि शून्य आरंभीकरण और असाइनमेंट अभिव्यक्ति के बीच कोई अनुक्रम बिंदु नहीं है? अनुक्रम बिंदु भी प्रासंगिक हैं (ऊपर देखें)? या सभी इनिशियलाइजर्स के मूल्यांकन के बाद शून्य इनिशियलाइज़ेशन होता है? यदि हां, तो a[2]समाप्त होना चाहिए 0

क्योंकि सी मानक स्पष्ट रूप से परिभाषित नहीं करता है कि यहां क्या होता है, मेरा मानना ​​है कि व्यवहार अपरिभाषित है (चूक से)।


1
अनिर्धारित के बजाय मैं यह तर्क दूंगा कि यह अनिर्दिष्ट है , जो कार्यान्वयन द्वारा व्याख्या के लिए चीजों को खुला छोड़ देता है।
कुछ प्रोग्रामर ने

1
"हम एक खरगोश छेद में आते हैं" LOL! कभी नहीं सुना है कि एक यूबी या अनिर्दिष्ट सामान के लिए।
B:овиЈ

2
@Someprogrammerdude मुझे नहीं लगता कि यह अनिर्दिष्ट हो सकता है (" व्यवहार जहां यह अंतर्राष्ट्रीय मानक दो या दो से अधिक संभावनाएं प्रदान करता है और आगे कोई आवश्यकता नहीं रखता है जिस पर किसी भी उदाहरण में चुना जाता है ") क्योंकि मानक वास्तव में कोई संभावनाएं प्रदान नहीं करता है जिसमें से चुनें। यह बस यह नहीं कहता कि क्या होता है, जो मुझे लगता है कि " अनिर्धारित व्यवहार के तहत आता है [...] इस अंतर्राष्ट्रीय मानक में संकेत दिया गया है [...] व्यवहार की किसी भी स्पष्ट परिभाषा की चूक से। "
मेलपोमिने

2
@ B @овиЈ यह न केवल अपरिभाषित व्यवहार के लिए, बल्कि परिभाषित व्यवहार के लिए भी बहुत अच्छा वर्णन है, जिसे समझाने के लिए इस तरह के धागे की आवश्यकता है।
gnasher729

1
@JohnBollinger अंतर यह है कि आप वास्तव में इसके आरंभकर्ता का a[0]मूल्यांकन करने से पहले सबोबेज को इनिशियलाइज़ नहीं कर सकते हैं , और किसी भी इनिशलाइज़र का मूल्यांकन करने में एक अनुक्रम बिंदु शामिल है (क्योंकि यह "पूर्ण अभिव्यक्ति" है)। इसलिए मेरा मानना ​​है कि हम जिस सबोबिज को संशोधित कर रहे हैं, वह उचित खेल है।
melpomene

22

मुझे समझ में नहीं आता, इसके बजाय a[0]प्रिंट क्यों करता 1है 0?

संभवतः पहले a[2]=1इनिशियलाइज़ करता है a[2], और एक्सप्रेशन के परिणाम को इनिशियलाइज़ करने के लिए उपयोग किया जाता हैa[0]

N2176 (C17 ड्राफ्ट) से:

6.7.9 इनिशियलाइज़ेशन

  1. आरम्भिक सूची के भावों का मूल्यांकन अनिश्चित काल के लिए एक दूसरे के संबंध में किया जाता है और इस प्रकार वह क्रम जिसमें कोई दुष्प्रभाव होता है अनिर्दिष्ट है। 154)

तो ऐसा लगता है कि आउटपुट 1 0 0 0 0 भी संभव हो सकता है।

निष्कर्ष: ऐसे इनिशियलाइज़र न लिखें जो फ्लाई पर इनिशियलाइज़ वैरिएबल को संशोधित करता है।


1
वह हिस्सा लागू नहीं होता है: यहां केवल एक इनिशियलाइज़र अभिव्यक्ति है, इसलिए इसे किसी भी चीज़ के साथ अनुक्रमित करने की आवश्यकता नहीं है।
melpomene

@melpomene वह {...}अभिव्यक्ति है जो आरंभ a[2]करता है 0और a[2]=1उप-अभिव्यक्ति जो प्रारंभ a[2]करता है 1
user694733

1
{...}एक लट आरंभिक सूची है। यह कोई अभिव्यक्ति नहीं है।
melpomene

@melpomene ठीक है, आप वहीं हो सकते हैं। लेकिन मैं अभी भी तर्क दूंगा कि अभी भी 2 प्रतिस्पर्धात्मक दुष्परिणाम हैं ताकि पैराग्राफ खड़ा हो।
user694733

@melpomene अनुक्रमित होने के लिए दो चीजें हैं: पहला इनिशियलाइज़र, और 0 तक अन्य तत्वों की सेटिंग
MM

6

मुझे लगता है कि C11 मानक इस व्यवहार को शामिल करता है और कहता है कि परिणाम अनिर्दिष्ट है , और मुझे नहीं लगता कि C18 ने इस क्षेत्र में कोई प्रासंगिक परिवर्तन किए हैं।

मानक भाषा को पार्स करना आसान नहीं है। मानक का प्रासंगिक अनुभाग §6.7.9 इनिशियलाइज़ेशन है । सिंटैक्स को इस रूप में प्रलेखित किया गया है:

initializer:
                assignment-expression
                { initializer-list }
                { initializer-list , }
initializer-list:
                designationopt initializer
                initializer-list , designationopt initializer
designation:
                designator-list =
designator-list:
                designator
                designator-list designator
designator:
                [ constant-expression ]
                . identifier

ध्यान दें कि शब्दों में से एक असाइनमेंट-एक्सप्रेशन है , और चूंकि a[2] = 1एक असाइनमेंट एक्सप्रेशन है, इसे गैर-स्टेटिक अवधि के साथ एरे के लिए इनिशियलाइज़र के अंदर अनुमति दी जाती है:

§4 स्थैतिक या थ्रेड स्टोरेज अवधि वाली किसी वस्तु के लिए एक इनिशियलाइज़र के सभी एक्सप्रेशन स्थिर अभिव्यक्ति या स्ट्रिंग लिटरल होंगे।

एक प्रमुख पैराग्राफ है:

§19 इनिशियलाइज़र लिस्ट ऑर्डर में घटित होगा, प्रत्येक इनिशियलाइज़र किसी विशेष सबबॉजेक्ट के लिए प्रदान किया जाता है, जो उसी सबोबिज के लिए पहले से सूचीबद्ध इनिशियलाइज़र को ओवरराइड करता है; 151) स्पष्ट रूप से प्रारंभ नहीं किए गए सभी उप-खंडों को प्रारंभिक रूप से समान किया जाएगा जो स्थिर भंडारण अवधि वाली वस्तुओं के समान हैं।

151) सबोबिज के लिए कोई भी इनिशलाइज़र जो ओवरराइड होता है और इसलिए इसका इनिशियलाइज़ करने के लिए इस्तेमाल नहीं किया जाता है कि सब -जेक्ट का मूल्यांकन नहीं किया जा सकता है।

और एक अन्य महत्वपूर्ण पैराग्राफ है:

§23 आरंभिक सूची के भावों का मूल्यांकन अनिश्चित काल के लिए एक दूसरे के संबंध में किया जाता है और इस प्रकार कोई भी दुष्प्रभाव उत्पन्न होने का क्रम अनिर्दिष्ट होता है। 152)

१५२) विशेष रूप से, मूल्यांकन आदेश सबऑब्जेक्ट इनिशियलाइज़ेशन के क्रम के समान नहीं होना चाहिए।

मुझे पूरा यकीन है कि पैरा §23 इंगित करता है कि प्रश्न में अंकन:

int a[5] = { a[2] = 1 };

अनिर्दिष्ट व्यवहार की ओर जाता है। असाइनमेंट a[2]एक साइड-इफ़ेक्ट है, और भावों का मूल्यांकन क्रम एक दूसरे के संबंध में अनिश्चित रूप से अनुक्रमित है। नतीजतन, मुझे नहीं लगता कि मानक के लिए अपील करने और दावा करने का एक तरीका है कि एक विशेष संकलक इसे सही या गलत तरीके से संभाल रहा है।


केवल एक आरंभीकरण सूची अभिव्यक्ति है, इसलिए not23 प्रासंगिक नहीं है।
मेलेपोमिन

2

मेरी अंडरस्टैंडिंग a[2]=1वैल्यू है 1 तो कोड बन जाता है

int a[5]={a[2]=1} --> int a[5]={1}

int a[5]={1}एक [0] = 1 के लिए मान प्रदान करें

इसलिए यह 1 के लिए 1 प्रिंट करता है [0]

उदाहरण के लिए

char str[10]={‘H’,‘a’,‘i’};


char str[0] = H’;
char str[1] = a’;
char str[2] = i;

2
यह एक [भाषा-वकील] सवाल है, लेकिन यह एक जवाब नहीं है जो मानक के साथ काम करता है, इस प्रकार यह अप्रासंगिक बना देता है। साथ ही 2 और अधिक गहराई से उत्तर उपलब्ध हैं और आपके उत्तर में कुछ भी नहीं जोड़ा गया है।
गुडबाय एसई

मुझे संदेह है। क्या मैंने जो अवधारणा गलत पोस्ट की है, क्या आप मुझे इसके साथ स्पष्ट कर सकते हैं?
कार्तिक

1
आप सिर्फ कारणों के लिए अटकलें लगाते हैं, जबकि मानक के प्रासंगिक भागों के साथ पहले से ही बहुत अच्छा जवाब है। सिर्फ यह कहना कि यह कैसे हो सकता है, सवाल यह नहीं है। यह इस बारे में है कि मानक क्या कहते हैं।
गुडबाय एसई

लेकिन सवाल के ऊपर पोस्ट करने वाले व्यक्ति ने कारण पूछा और ऐसा क्यों होता है? तो केवल मैंने इस उत्तर को छोड़ दिया। लेकिन अवधारणा सही है।
कार्तिका

ओपी ने पूछा " क्या यह अपरिभाषित व्यवहार है? "। आपका जवाब नहीं है।
melpomene

1

मैं पहेली के लिए एक छोटा और सरल उत्तर देने की कोशिश करता हूं: int a[5] = { a[2] = 1 };

  1. पहले a[2] = 1सेट किया गया है। इसका मतलब है कि सरणी कहती है:0 0 1 0 0
  2. लेकिन निहारना, यह देखते हुए कि आपने इसे { }कोष्ठक में किया था , जिसका उपयोग क्रम में सरणी को इनिशियलाइज़ करने के लिए किया जाता है, यह पहला मान लेता है (जो है 1) और इसे सेट करता है a[0]। यह वैसा ही है जैसा int a[5] = { a[2] };हम पहले ही मिल चुके हैं a[2] = 1। परिणामी सरणी अब है:1 0 1 0 0

एक और उदाहरण: int a[6] = { a[3] = 1, a[4] = 2, a[5] = 3 };- भले ही आदेश कुछ हद तक मनमाना है, यह मानते हुए कि यह बाएं से दाएं जाता है, यह इन 6 चरणों में जाएगा:

0 0 0 1 0 0
1 0 0 1 0 0
1 0 0 1 2 0
1 2 0 1 2 0
1 2 0 1 2 3
1 2 3 1 2 3

1
A = B = C = 5एक घोषणा (या आरंभीकरण) नहीं है। यह एक सामान्य अभिव्यक्ति है जो पार्स करता है A = (B = (C = 5))क्योंकि =ऑपरेटर सही सहयोगी है। यह वास्तव में यह समझाने में मदद नहीं करता है कि आरंभीकरण कैसे काम करता है सरणी वास्तव में मौजूदा शुरू होती है जब इसे जिस ब्लॉक में परिभाषित किया गया है वह दर्ज किया गया है, जो वास्तविक परिभाषा निष्पादित होने से बहुत पहले हो सकता है।
मेलेपोमेन सेप

1
" यह बाएं से दाएं जाता है, प्रत्येक आंतरिक घोषणा के साथ शुरू होता है " गलत है। सी मानक स्पष्ट रूप से कहता है " आदेश जिसमें प्रारंभिक सूची सूची के बीच कोई दुष्प्रभाव होता है अनिर्दिष्ट है। "
melpomene

1
" आप पर्याप्त समय में मेरे उदाहरण से कोड का परीक्षण करते हैं और देखें कि क्या परिणाम सुसंगत हैं। " ऐसा नहीं है कि यह कैसे काम करता है। आप समझ नहीं पाते हैं कि अपरिभाषित व्यवहार क्या है। सी में सब कुछ डिफ़ॉल्ट रूप से अपरिभाषित व्यवहार है; यह सिर्फ इतना है कि कुछ हिस्सों में व्यवहार होता है जो मानक द्वारा परिभाषित किया गया है। यह साबित करने के लिए कि कुछ ने व्यवहार को परिभाषित किया है, आपको मानक का हवाला देना चाहिए और दिखाना चाहिए कि यह क्या परिभाषित करता है कि क्या होना चाहिए। ऐसी परिभाषा के अभाव में, व्यवहार अपरिभाषित है।
मेलेपोमेन

1
बिंदु (1) में अभिकथन यहाँ महत्वपूर्ण प्रश्न पर एक बड़ी छलांग है: क्या तत्व का प्रारंभिक इनिशियलाइज़ेशन एक [2] से 0 होता है जो a[2] = 1इनिलाइज़र अभिव्यक्ति के साइड इफेक्ट लागू होने से पहले होता है? देखा गया परिणाम ऐसा है जैसे यह था, लेकिन मानक यह निर्दिष्ट नहीं करता है कि ऐसा होना चाहिए। यह विवाद का केंद्र है, और यह जवाब पूरी तरह से इसे अनदेखा करता है।
जॉन बोलिंगर

1
"अपरिभाषित व्यवहार" एक संकीर्ण अर्थ के साथ एक तकनीकी शब्द है। इसका मतलब यह नहीं है कि "व्यवहार हम वास्तव में निश्चित नहीं हैं"। यहाँ मुख्य अंतर्दृष्टि यह है कि कोई भी परीक्षण, जिसमें कोई संकलक नहीं है, कभी भी एक विशेष कार्यक्रम नहीं दिखा सकता है या मानक के अनुसार अच्छी तरह से व्यवहार नहीं किया जाता है , क्योंकि यदि किसी कार्यक्रम में अपरिभाषित व्यवहार है, तो संकलक को कुछ भी करने की अनुमति है - जिसमें काम करना भी शामिल है पूरी तरह से अनुमानित और उचित तरीके से। यह केवल कार्यान्वयन के मुद्दे की गुणवत्ता नहीं है जहां कंपाइलर लेखक चीजों को दस्तावेज करते हैं - यह अनिर्दिष्ट या कार्यान्वयन-परिभाषित व्यवहार है।
जेरोइन मोस्टर्ट

0

असाइनमेंट a[2]= 1एक अभिव्यक्ति है जिसका मूल्य है 1, और आपने अनिवार्य रूप से लिखा है int a[5]= { 1 };(साइड इफेक्ट के साथ जो a[2]सौंपा गया है 1)।


लेकिन यह स्पष्ट नहीं है कि जब साइड इफेक्ट का मूल्यांकन किया जाता है और संकलक के आधार पर व्यवहार बदल सकता है। यह भी मानक बताता है कि यह अपरिभाषित व्यवहार है जो संकलक के विशिष्ट स्पष्टीकरण के लिए स्पष्टीकरण देने में सहायक नहीं है।
गुडबाय एसई

@KamiKaze: निश्चित रूप से, मूल्य 1 दुर्घटना से वहाँ उतरा।
यवेस डाएट

0

मेरा मानना ​​है कि, int a[5]={ a[2]=1 };एक प्रोग्रामर के लिए यह एक अच्छा उदाहरण है कि वह खुद को अपने पैरों में फंसाए।

मुझे यह int a[5]={ [2]=1 };सोचकर ललचाया जा सकता है कि आपका मतलब क्या था जो कि एक C99 नामित इनिशियलाइज़र सेटिंग एलिमेंट 2 से 1 और बाकी शून्य होगा।

उस दुर्लभ मामले में जिसका आप वास्तव में मतलब रखते हैं int a[5]={ 1 }; a[2]=1;, तो यह लिखने का एक अजीब तरीका होगा। किसी भी तरह, यह वही है जो आपके कोड को उबालता है, भले ही कुछ लोगों ने बताया कि यह अच्छी तरह से परिभाषित नहीं है कि जब a[2]वास्तव में लिख दिया जाता है। यहाँ नुकसान यह है कि a[2]=1एक निर्दिष्ट आरंभीकरण नहीं है, बल्कि एक सरल असाइनमेंट है जिसका मूल्य 1 है।


ऐसा लगता है कि यह भाषा-वकील विषय मानक ड्राफ्ट से संदर्भ पूछ रहा है। यही कारण है कि आपको नीचा दिखाया जाता है (मैंने ऐसा नहीं किया जैसा कि आप देखते हैं कि मैं उसी कारण से अस्वीकृत हूं)। मुझे लगता है कि आपने जो लिखा है वह पूरी तरह से ठीक है लेकिन लगता है कि ये सभी भाषा के वकील या तो कमिटेड हैं या ऐसा ही कुछ है। इसलिए वे बिल्कुल भी मदद नहीं मांग रहे हैं कि वे यह जांचने की कोशिश कर रहे हैं कि ड्राफ्ट मामले को कवर करता है या नहीं और यहां के अधिकांश लोगों को ट्रिगर किया जाता है यदि आप जवाब देते हैं जैसे आप उनकी मदद कर रहे हैं। मुझे लगता है कि मेरा उत्तर हटा देना बीमार है :) अगर यह विषय नियम स्पष्ट रूप से सहायक होता है
अब्दुर्रहीम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.