2010-02-23 12 views
28

जब मुझे पहली बार सी से पेश किया गया था तो मुझे हमेशा कार्य के शीर्ष पर अपने चर घोषित करने के लिए कहा गया था। अब जब मुझे भाषा का एक मजबूत समझ है तो मैं कोडिंग शैली पर अपने प्रयासों पर ध्यान केंद्रित कर रहा हूं, विशेष रूप से मेरे चर के दायरे को सीमित कर रहा हूं। मैंने दायरे को सीमित करने के लाभों के बारे में पढ़ा है और मैं एक दिलचस्प उदाहरण में आया हूं। जाहिर है, C99 आपको ऐसा करने की अनुमति देता है ...मैं कानूनी तौर पर सी 99 में एक चर घोषित कर सकता हूं?

for (int i = 0; i < 10; i++) 
{ 
    puts("hello"); 
} 

मैंने सोचा था कि एक चर गुंजाइश भीतर सबसे घुंघराले ब्रेसिज़ { } आसपास के द्वारा सीमित था, लेकिन ऊपर के उदाहरण में int i में सीमित हो गया लगता है फॉर-लूप के घुंघराले ब्रेसिज़ द्वारा गुंजाइश, भले ही इसे उनके बाहर घोषित किया गया हो।

मैंने उपरोक्त उदाहरण को fgets() के साथ विस्तारित करने का प्रयास किया जो मैंने सोचा था कि ऐसा कुछ ऐसा था, लेकिन इन दोनों ने मुझे एक वाक्यविन्यास त्रुटि दी।

fgets(char fpath[80], 80, stdin); * नोट **

fgets(char* fpath = malloc(80), 80, stdin);

तो, बस जहां वास्तव में चर C99 में घोषित करने के लिए यह कानूनी है देखते हैं? क्या फॉर-लूप उदाहरण नियम के लिए अपवाद था? क्या यह while और do while लूप पर भी लागू होता है?

* ध्यान दें **: मैं भी यकीन है कि यह वाक्य रचना सही होगा, भले ही मैं चार सरणी वहाँ की घोषणा कर सकता है fgets() के बाद से चार की सरणी 80 को नहीं सूचक चार को सूचक की तलाश में है नहीं कर रहा हूँ । यही कारण है कि मैंने malloc() संस्करण की कोशिश की।

+1

भले ही यह कानूनी है या नहीं, आपको इस तरह के मॉलोक को कभी भी कॉल नहीं करना चाहिए क्योंकि आप यह जांच नहीं रहे हैं कि यह न्यूल लौटता है या नहीं, और न ही आप आवंटित ढेर मेमोरी को मुक्त कर सकते हैं, क्योंकि एफपीएथ तुरंत दायरे से बाहर हो जाता है। – Jeff

उत्तर

31

सी 99 में, आप अपने चर को घोषित कर सकते हैं जहां आपको उनकी आवश्यकता है, जैसे सी ++ आपको ऐसा करने की अनुमति देता है।

void somefunc(char *arg) 
{ 
    char *ptr = "xyz"; 
    if (strcmp(arg, ptr) == 0) 
    { 
     int abc = 0; /* Always could declare variables at a block start */ 

     somefunc(arg, &ptr, &abc); 

     int def = another_func(abc, arg); /* New in C99 */ 
     ...other code using def, presumably... 
    } 
} 
  • आप पाश 'के लिए' एक के नियंत्रण भाग में एक चर घोषणा कर सकते हैं:

    for (int x = 0; x < 10; x++) /* New in C99 */ 
    
  • आप एक 'जबकि' पाश के नियंत्रण हिस्सा है या में एक चर की घोषणा नहीं कर सकते हैं एक 'अगर' कथन।

  • आप फ़ंक्शन कॉल में एक चर घोषित नहीं कर सकते हैं।
  • जाहिर है, आप किसी भी लूप या 'if' कथन के बाद ब्लॉक में चर (और हमेशा कर सकते हैं) घोषित कर सकते हैं।

C99 मानक का कहना है:

6.8.5.3 बयान

बयान

for (clause-1 ; expression-2 ; expression-3) statement 

बर्ताव के लिए इस प्रकार है: अभिव्यक्ति अभिव्यक्ति -2 है नियंत्रित अभिव्यक्ति जो मूल्यांकन किया गया है लूप बॉडी के प्रत्येक निष्पादन के लिए आगे।अभिव्यक्ति अभिव्यक्ति-3 लूप बॉडी के प्रत्येक निष्पादन के बाद शून्य अभिव्यक्ति के रूप में मूल्यांकन किया गया है। यदि क्लॉज -1 घोषणा है, तो घोषित किए गए किसी भी चर का दायरा घोषणा का शेष है और अन्य लूप सहित पूरे लूप; यह नियंत्रण अभिव्यक्ति के पहले मूल्यांकन से पहले निष्पादन के क्रम में पहुंच गया है। यदि क्लॉज -1 एक अभिव्यक्ति है, तो यह को नियंत्रित अभिव्यक्ति के पहले मूल्यांकन से पहले एक शून्य अभिव्यक्ति के रूप में मूल्यांकन किया गया है।

+0

विस्तृत टिप्पणी के लिए धन्यवाद और मानक – SiegeX

8

पहली बात मैं ध्यान दें चाहते हैं कि आप

for (int i = 0; i < 10; i++) { 
    puts("hello"); 
} 

और

fgets(char* fpath = malloc(80), 80, stdin); 

पहले भ्रमित नहीं होना चाहिए है एक नियंत्रण संरचना है, जबकि दूसरा एक समारोह कॉल है। नियंत्रण संरचना फ़ंक्शन कॉल के तरीके से बहुत अलग तरीके से अपने माता-पिता() के अंदर पाठ का मूल्यांकन करती है।

दूसरी बात है ... मुझे समझ नहीं आता कि आप क्या कहना द्वारा कोशिश कर रहे हैं:

संकलक तुरंत आपको एक त्रुटि है, तो आप के लिए लूप के अंदर मैं इस्तेमाल करने की कोशिश दे देंगे तन।

आपके द्वारा लूप के लिए सूचीबद्ध कोड सी में एक बहुत ही सामान्य संरचना है और परिवर्तनीय "i" वास्तव में लूप बॉडी के अंदर उपलब्ध होना चाहिए। हां, निम्नलिखित कार्य करना चाहिए:

int n = 0; 
for (int i = 0; i < 10; i++) { 
    n += i; 
} 

क्या मैं आप जो कह रहा हूं उसे गलत तरीके से पढ़ रहा हूं?

+0

संख्या का संदर्भ देने के लिए धन्यवाद, आप गलत तरीके से गलत नहीं थे लेकिन स्पष्ट रूप से मैंने अपने प्रश्न में पोस्ट किए गए एसओ लिंक पर कुछ गलत जानकारी पढ़ी, जिसमें कहा गया कि यह संकलित नहीं होगा। जाहिर है, अधिक सही कथन होना चाहिए था कि यह गुजरने के बिना संकलित करने में असफल हो जाएगा -std = c99 से 'gcc'। क्या आप एक नियंत्रण संरचना के भीतर एक नियंत्रण संरचना के भीतर टेक्स्ट के मूल्यांकन पर थोड़ा और अंतर्दृष्टि प्रदान कर सकते हैं क्योंकि मुझे लगता है कि यह निश्चित रूप से मेरी सवाल उठाने का प्रयास कर रहा है। – SiegeX

+0

आपके द्वारा लिंक किए गए प्रश्न में लॉजिकल त्रुटि के साथ लूप का एक उदाहरण पोस्ट किया गया है, (लूप के अंत में अर्धविराम को नोटिस करें) जो उस तर्क त्रुटि के कारण संकलित करने में असफल होगा। एक सामान्य पर्याप्त त्रुटि है कि SO पर कई सवाल हैं। – nos

2

अपने for/fgets भ्रम के संबंध में लब्बोलुआब यह है कि जबकि "enclosing ब्रेसिज़ दायरे को नियंत्रित" सी समय के सबसे में सही नियम है, वहाँ C99 में गुंजाइश (सी ++ से उधार) के बारे में एक और नियम है कि कहते हैं कि एक नियंत्रण संरचना के प्रस्तावना में घोषित एक चर (यानी for, while, if) संरचना के शरीर में गुंजाइश है (और शरीर के बाहर दायरे में नहीं है)।

+2

स्पष्ट रूप से यह केवल 'for' loops के साथ काम करता है लेकिन उत्तर के लिए +1। – SiegeX

+1

ओह। यह सी ++ में 'if' और' while' के लिए काम करता है, इसलिए मुझे लगता है कि मुझे लगता है कि सी 99 ने पूरी चीज उधार ली होगी, सिर्फ 'भाग' के लिए नहीं। –

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

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