2017-08-13 30 views
51

यह प्रोग्राम array के तत्वों को मुद्रित करना है, लेकिन जब यह चलाया जाता है, तो कोई आउटपुट नहीं दिखाया जाता है।लूप शुरू -1 पर कुछ भी प्रिंट नहीं करता

#include <stdio.h> 

#define TOTAL_ELEMENTS (sizeof(array)/sizeof(array[0])) 

int array[] = { 23, 34, 12, 17, 204, 99, 16 }; 

int main() { 
    int d; 
    for (d = -1; d <= (TOTAL_ELEMENTS - 2); d++) 
     printf("%d\n", array[d + 1]); 
    return 0; 
} 

यह प्रोग्राम कोई आउटपुट क्यों नहीं दिखाता है?

+37

एक हार्डकोडेड चर नाम के साथ एक मैक्रो परेशानी के लिए पूछ रहा है। – jackarms

+1

'd = 0' बदलना आउटपुट चीजें करता है हालांकि –

+1

@ टोनीटैनस लेकिन यह समझाता नहीं है कि OP – CIsForCookies

उत्तर

145

sizeof एक हस्ताक्षरित पूर्णांक देता है, इसलिए TOTAL_ELEMENTS भी हस्ताक्षरित है।

d पर हस्ताक्षर किए गए हैं। प्रारंभ में, d-1 है। हालांकि, तुलना करते समय, d स्पष्ट रूप से हस्ताक्षरित करने के लिए टाइपकास्ट है, इसलिए यह अब -1TOTAL_ELEMENTS की तुलना में नहीं है, यह वास्तव में UINT_MAX है (जो मेरी मशीन पर 4294967295 है, लेकिन अन्य के लिए भिन्न हो सकता है)।

इसके अलावा,

आप इसे ठीक करना चाहते हैं, int को TOTAL_ELEMENTS टाइपकास्ट:

for(d = -1; d <= (int)(TOTAL_ELEMENTS - 2); d++) 

यह प्रिंट होगा:

23 
34 
12 
17 
204 
99 
16 

आपकी अपेक्षा से कम के रूप में। हस्ताक्षरित हस्ताक्षरित तुलना के विषय पर अधिक जानकारी के लिए आप Comparison operation on unsigned and signed integers पर भी देखना चाह सकते हैं।

यह ध्यान देने योग्य है कि संकलक चेतावनी को चालू कर दिया जाएगा लायक है आप यह पता लगाने की क्या चल रहा था (के रूप में अपने comment में हाइड द्वारा मनाया) मदद की:

$ gcc -Wall -Wextra test.c 
test.c:7:17: warning: comparison of integers of different signs: 'int' and 'unsigned long' [-Wsign-compare] 
     for(d = 0; d < TOTAL_ELEMENTS; d++) 
       ~^~~~~~~~~~~~~~~ 
1 warning generated. 

वैकल्पिक रूप से, क्यों शुरू नहीं d0 पर और इसके बजाय TOTAL_ELEMENTS - 1 पर चलाएं? आप टाइपकास्ट को भी छोड़ सकते हैं, जो केवल d = -1 के कोने मामले के लिए जरूरी है।

for(d = 0; d < TOTAL_ELEMENTS; d++) 
    printf("%d\n", array[d]); 

एक फुटनोट के रूप में, यहाँ प्रासंगिक C99 स्टैंडर्ड अंश इस प्रकार हैं:

  1. 6.3.1.8p2 अहस्ताक्षरित प्रकार पर हस्ताक्षर किए से रूपांतरण परिभाषित करता है।

    संकार्य अहस्ताक्षरित पूर्णांक प्रकार है कि रैंक अधिक से अधिक या अन्य संकार्य के प्रकार के पद के लिए बराबर है, तो पर हस्ताक्षर किए पूर्णांक प्रकार के साथ संकार्य अहस्ताक्षरित पूर्णांक के साथ संकार्य के प्रकार में बदल जाती है प्रकार। पर हस्ताक्षर किए प्रतिनिधित्व करने के लिए UINT_MAX + 1 जोड़कर:

  2. 6.3.1.3p2 रूपांतरण किया जाता है परिभाषित करता है।

    तो नए प्रकार अहस्ताक्षरित है, मूल्य बार-बार जोड़ने या अधिकतम मूल्य कि नए प्रकार में व्यक्त किया जा सकता जब तक मूल्य नए प्रकार की सीमा में है एक से अधिक घटा कर बदल जाती है।

    तो -1 =>-1 + (UINT_MAX + 1) = UINT_MAX, इस स्थिति के लिए।

35

मेरे जीसीसी आउटपुट इस चेतावनी:

warning: comparison of integers of different signs: 'int' and 'unsigned long' [-Wsign-compare] 
     for(d = 0; d < TOTAL_ELEMENTS; d++) 

जिसका अर्थ है कि (TOTAL_ELEMENTS-2)unsigned int जबकि dsigned int है। यह (unsigned int)(-1) > (TOTAL_ELEMENTS-2) के बाद, d के आरंभिक मान के लिए अभिव्यक्ति को हमेशा false बनाता है।

+19

हाँ। सबक: हमेशा सभी चेतावनियों को सक्षम करें और उन्हें पढ़ें –

+1

अभिव्यक्ति * हमेशा झूठी * नहीं है, यह 'd' के प्रारंभिक मान के लिए गलत है। – chqrlie

4

विभिन्न अभिन्न प्रकारों के बीच बाइनरी संचालन सामान्य "सामान्य" प्रकार के भीतर किया जाता है जिसे सामान्य अंकगणितीय रूपांतरण कहा जाता है। तो int डी गायन प्रकार का मूल्य -1 के साथ शुरू किया गया है। जो जब हस्ताक्षरित int में परिवर्तित होता है तो यह अधिकतम हस्ताक्षरित int वापस कर देगा जो TOTAL_ELEMENTS द्वारा लौटाए गए मान से कहीं अधिक है।

+1

आपके उत्तर में 'हस्ताक्षरित int' 'size_t' होना चाहिए। इसके अलावा, आप बिंदु पर हैं। – StoryTeller

संबंधित मुद्दे