कैसे सरणी [100] = {0} पूरे सरणी को 0 पर सेट करता है?


140

संकलक में मान कैसे भरता है char array[100] = {0};? इसके पीछे क्या जादू है?

मैं जानना चाहता था कि आंतरिक रूप से संकलक कैसे आरंभ करता है।


1
C या C ++ में? वे दो अलग-अलग प्रश्न हैं।
टॉबी स्पाईट

जवाबों:


163

यह जादू नहीं है।

सी में इस कोड का व्यवहार सी विनिर्देश के खंड 6.7.8.21 में वर्णित है ( सी कल्पना का ऑनलाइन ड्राफ्ट ): उन तत्वों के लिए जिनके पास एक निर्दिष्ट मूल्य नहीं है, संकलक पॉइंटर्स को NULL और अंकगणितीय प्रकारों को शून्य में आरंभ करता है ( और पुनरावर्ती समुच्चय पर यह लागू होता है)।

C ++ में इस कोड का व्यवहार C ++ विनिर्देशन ( C ++ युक्ति का ऑनलाइन मसौदा ) की धारा 8.5.1.7 में वर्णित है : संकलक उन तत्वों को आरंभ करता है जिनमें निर्दिष्ट मान नहीं होता है।

यह भी ध्यान दें कि C ++ (लेकिन C नहीं) में, आप एक खाली इनिशियलाइज़र सूची का उपयोग कर सकते हैं, जिससे कंपाइलर एरे के सभी तत्वों को एकत्रित कर सकता है:

char array[100] = {};

जब आप ऐसा करते हैं तो संकलक किस तरह का कोड उत्पन्न कर सकता है, इस सवाल पर एक नज़र डालें: सरणी 0-प्रारंभ से अजीब विधानसभा


क्या सभी सी कंपाइलर ऐसा करते हैं? मुझे विश्वास था कि केवल विजुअल स्टूडियो ही ऐसा कर रहा है।
JFA

1
c ++ स्पेक्स का ऑनलाइन ड्राफ्ट टूट गया, किसी के पास नया लिंक है?
बेहरोज करजू

35

कंपाइलर डेवलपर्स के लिए कार्यान्वयन है।

यदि आपका प्रश्न "इस तरह की घोषणा के साथ क्या होगा" - संकलक आपके द्वारा प्रदान किए गए मान के लिए पहला सरणी तत्व सेट करेगा (0) और अन्य सभी को शून्य पर सेट किया जाएगा क्योंकि यह लोप किए गए सरणी तत्वों के लिए डिफ़ॉल्ट मान है।


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

10
यदि आप पहले तत्व के लिए कोई मान सेट नहीं करते हैं, तो रयान, जो कि संपूर्ण ऐरे है 0.
qrdl

1
C ++ के लिए एक बाउंडेड ऐरे के लिए एक खाली इनिशियलाइज़र सूची सभी तत्वों को डिफ़ॉल्ट-इनिशियलाइज़ करती है।
dalle

2
@NatanYellin मैंने कहाँ कहा कि यह अपरिभाषित है? कमेंट और डाउनवोट करने से पहले पूरा जवाब जरूर पढ़ें।
qrdl

1
@qrdl तुम सही हो। मैंने कार्यान्वयन के बारे में आपकी टिप्पणी को गलत समझा। दुर्भाग्य से, मैं अपना वोट अब नहीं बदल सकता।
नाटन येलिन

27

यदि आपका कंपाइलर GCC है तो आप सिंटैक्स का उपयोग भी कर सकते हैं:

int array[256] = {[0 ... 255] = 0};

कृपया http://gcc.gnu.org/oniltocs/gcc-4.1.2/gcc/Designated-Inits.html#Designated-Inits देखें , और ध्यान दें कि यह एक कंपाइलर-विशिष्ट सुविधा है।


स्वागत हे! चूँकि आपने इस प्रकार की और भी तरकीबें
तलाशने के

1
यदि आप चुनते हैं तो आप निश्चित रूप से ऐसा कर सकते हैं, लेकिन इस तरह के संकलक-विशिष्ट एक्सटेंशन पर भरोसा करने के स्पष्ट नुकसान हैं।
डैन ओल्सन

@ डैन ओल्सन अपना प्रश्न खुद संकलक के बारे में पूछ रहे हैं और इसलिए उन्होंने यह पोस्ट किया है। यदि आपको लगता है कि यह बेकार है, तो मैं हटा दूंगा।
lakshmanaraj

5
यह बेकार नहीं है, यह दिलचस्प है। चेतावनी सिर्फ ध्यान देने योग्य है।
डैन ओल्सन

2
यह इस तरह से सामान है जो मुझे एसओ के पास वापस
लाता है

19

यह निर्भर करता है कि आपने यह इनिशियलाइज़ेशन कहाँ रखा है।

यदि ऐरे में जैसा स्थिर है

char array[100] = {0};

int main(void)
{
...
}

फिर यह वह कंपाइलर है जो प्रोग्राम के डेटा सेगमेंट में 100 0 बाइट्स को आरक्षित करता है। इस मामले में आप इनिशियलाइज़र को छोड़ सकते थे।

यदि आपकी सरणी ऑटो है, तो यह एक और कहानी है।

int foo(void)
{
char array[100] = {0};
...
}

इस मामले में फ़ंक्शन फू के हर कॉल पर आपको एक छिपी हुई याद होगी।

उपरोक्त कोड के बराबर है

int foo(void)
{ 
char array[100];

memset(array, 0, sizeof(array));
....
}

और यदि आप इनिशियलाइज़र को छोड़ देते हैं तो आपके एरे में रैंडम डेटा (स्टैक का डेटा) होगा।

यदि आपके स्थानीय सरणी को स्थिर की तरह घोषित किया जाता है

int foo(void)
{ 
static char array[100] = {0};
...
}

फिर यह तकनीकी रूप से पहले वाले के समान ही मामला है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.