दिलचस्प पोस्ट
रिक्त कोष्ठ के साथ डिफ़ॉल्ट निर्माता मैं स्वयं को हस्ताक्षर किए प्रमाण पत्र कैसे स्वीकार कर सकता हूं? एक अजगर मॉड्यूल आयात नहीं किया जा सकता जो निश्चित रूप से इंस्टॉल किया गया है (मशीनीज़) Python का उपयोग कर स्ट्रिंग से यूआरएल निकालने का सबसे साफ तरीका क्या है? चर स्तंभ नामों के साथ डायनामिक अपडेट स्टेटमेंट बाहरी URL से JSON डेटा प्राप्त करें और इसे एक सादे पाठ में प्रदर्शित करें एक मेज के अंदर फार्म जावा में ध्रुवीय ग्राफ खींचना एंड्रॉइड में एक दृश्य घूम रहा है ऐप के लिए डिफॉल्ट डीफॉल्ट थीम का उपयोग कैसे करें? एक वस्तु के रूप में संख्यात्मक कुंजी के साथ एक सरणी कास्टिंग करना सरणी में नए तत्व कैसे जोड़ सकते हैं? GitHub को धकेलने में त्रुटि – रिपॉजिटरी डेटाबेस को ऑब्जेक्ट जोड़ने के लिए अपर्याप्त अनुमति फोर्स Google खाता चयनकर्ता टेक्स्टव्यू में सभी यूनिकोड वर्ण प्रदर्शित करें

सी में वैरिएबल घोषणा प्लेसमेंट

मैंने लंबे समय से सोचा था कि सी में, सभी चर को समारोह की शुरुआत में घोषित करना था। मुझे पता है कि सी 99 में, नियम सी ++ के समान हैं, लेकिन C89 / ANSI सी के लिए वेरिएबल घोषित प्लेसमेंट नियम क्या हैं?

निम्नलिखित कोड gcc -std=c89 और gcc -ansi साथ सफलतापूर्वक संकलित:

 #include <stdio.h> int main() { int i; for (i = 0; i < 10; i++) { char c = (i % 95) + 32; printf("%i: %c\n", i, c); char *s; s = "some string"; puts(s); } return 0; } 

c और s की घोषणा C89 / ANSI मोड में एक त्रुटि के कारण नहीं होनी चाहिए?

वेब के समाधान से एकत्रित समाधान "सी में वैरिएबल घोषणा प्लेसमेंट"

यह सफलतापूर्वक संकलित है क्योंकि जीसीसी इसे जीएनयू एक्सटेंशन के रूप में अनुमति देता है, हालांकि यह C89 या ANSI मानक का हिस्सा नहीं है। यदि आप उन मानकों के सख्ती से पालन करना चाहते हैं, तो आपको -pedantic ध्वज को पास करना होगा

सी 8 9 के लिए, आपको एक स्कोप ब्लॉक की शुरुआत में अपने सभी चर को घोषित करना होगा।

इसलिए, आपके char c घोषणा वैध है क्योंकि यह लूप स्कोप ब्लॉक के शीर्ष पर है। लेकिन, char *s घोषणा एक त्रुटि होना चाहिए

ब्लॉक के शीर्ष पर वैरिएबल घोषणाओं को समूहित करना पुराने, आदिम सी कंपाइलरों की सीमाओं के कारण होने वाली विरासत है। सभी आधुनिक भाषाओं की सिफारिश की जाती है और कभी-कभी नवीनतम बिंदुओं पर स्थानीय चर की घोषणा भी लागू होती है: जहां उन्हें पहले आरम्भ किया गया था क्योंकि यह गलती से यादृच्छिक मूल्य का उपयोग करने के जोखिम से मुक्त हो जाता है। घोषणा और आरंभ को अलग करने से आप "const" (या "अंतिम") का उपयोग करने से रोक सकते हैं जब आप कर सकते थे

सी ++ दुर्भाग्य से सी के साथ पिछड़े संगतता के लिए पुराने, शीर्ष घोषणापत्र को स्वीकार करना जारी रखता है (कई अन्य लोगों के एक सी अनुकूलता खींचें …) लेकिन सी ++ इसे से दूर जाने की कोशिश करता है:

  • सी ++ संदर्भों का डिज़ाइन ब्लॉक समूह के इस तरह के शीर्ष को भी अनुमति नहीं देता है।
  • यदि आप सी ++ लोकल ऑब्जेक्ट की घोषणा और आरम्भिकता को अलग करते हैं तो आप कुछ के लिए एक अतिरिक्त निर्माता की लागत का भुगतान करते हैं। अगर ना-आरजे कन्स्ट्रक्टर अस्तित्व में नहीं है, फिर आपको दोनों को अलग करने की भी अनुमति नहीं है!

C99 इस दिशा में सी चलती है।

यदि आपको स्थानीय चर को घोषित नहीं किया जाता है, तो आपको इसके बारे में चिंतित होने का मतलब है कि इसका मतलब है कि आपकी एक बड़ी समस्या है: अवरुद्ध ब्लॉक बहुत लंबा है और इसे विभाजित किया जाना चाहिए।

https://www.securecoding.cert.org/confluence/display/cplusplus/DCL19-CPP.+Initialize+automatic+local+variables+on+declaration

वाक्यविन्यास, दृष्टिकोण के बजाय एक रखरखाव से, विचार के कम से कम तीन गाड़ियों हैं:

  1. समारोह की शुरुआत में सभी चर की घोषणा करें ताकि वे एक ही स्थान पर हों और आप एक नज़र में व्यापक सूची देख सकेंगे।

  2. उन सभी जगहों को घोषित करें, जहां तक ​​वे पहली बार उपयोग किए जा रहे हैं, तो आपको पता चल जाएगा कि प्रत्येक की आवश्यकता क्यों है।

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

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

मैं कभी-कभी एक छोटे क्षेत्र ब्लॉक के भीतर चर की घोषणा करता हूं, लेकिन केवल एक अच्छे कारण के लिए, जिसमें से मेरे पास बहुत कम है एक उदाहरण एक fork() बाद हो सकता है, केवल बाल प्रक्रिया द्वारा आवश्यक चर घोषित करने के लिए मेरे लिए, यह दृश्य सूचक उनके उद्देश्य का उपयोगी अनुस्मारक है।

जैसा कि दूसरों के द्वारा बताया गया है, इस संदर्भ में जीसीसी (और संभवत: अन्य कंपाइलर, उन तर्कों के आधार पर, जिन्हें वे कहते हैं) पर भी 'C89' मोड में, जब तक कि आप 'पेंडेंटिक' जांच का उपयोग न करते हों ईमानदार होने के लिए, बहुत अच्छे कारणों पर पेंडेंट नहीं हैं; गुणवत्ता वाले आधुनिक कोड को हमेशा चेतावनियों के बिना संकलित करना चाहिए (या बहुत कम जहां आप जानते हैं कि आप कुछ खास कर रहे हैं जो संकलक को एक संभावित गलती के रूप में संदिग्ध है), इसलिए यदि आप अपने कोड को पेंडीकंटिक सेटअप के साथ संकलित नहीं कर सकते तो संभवतः उसे कुछ ध्यान देने की आवश्यकता है

सी 8 9 की आवश्यकता है कि प्रत्येक क्षेत्र में किसी अन्य बयान के पहले वेरिएबल को घोषित किया जाए, बाद में मानकों का उपयोग करने के करीब घोषणा (जो दोनों अधिक सहज और अधिक कुशल हो) की अनुमति दी जाती है, खासकर एक साथ घोषणा और लूप नियंत्रण चर के लिए 'लूप' के लिए लूप का आरम्भिकरण।

मैं स्पष्ट विवरण के लिए जीसीसी वर्जन 4.7.0 के मैनुअल से कुछ बयानों का उद्धृत करूंगा।

"संकलक कई मानक मानकों को स्वीकार कर सकता है, जैसे 'c90' या 'c ++ 98', और उन मानकों के जीएनयू बोलियों, जैसे 'gnu90' या 'gnu + + 98'। आधार मानक निर्दिष्ट करके, संकलक ऐसे मानक और उन GNU एक्सटेंशन का उपयोग करने वाले सभी कार्यक्रमों को स्वीकार करेंगे जो इसका विरोध नहीं करते हैं.उदाहरण के लिए, '-std = c90' जीसीसी की कुछ विशेषताओं को बंद कर देता है जो ISO C90 के साथ असंगत है, जैसे एएसएम और टाइप कीवर्ड्स, लेकिन नहीं अन्य जीएनयू एक्सटेंशन जिनमें आईएसओ सी 90 में कोई अर्थ नहीं है, जैसे मध्यवर्ती शब्द को छोड़कर: अभिव्यक्ति। "

मुझे लगता है कि आपके प्रश्न का मुख्य बिंदु यह है कि जीसीसी सी 8 9 के अनुरूप नहीं है, भले ही विकल्प "-स्टडी = सी 8 9" का प्रयोग किया जाता है। मुझे आपके जीसीसी के संस्करण का पता नहीं है, लेकिन मुझे लगता है कि इसमें बड़ा अंतर नहीं होगा जीसीसी के डेवलपर ने हमें बताया है कि विकल्प "-स्टडी = सी 8 9" का मतलब सिर्फ एक्सटेंशन है जो सी 8 9 का विरोध करता है। इसलिए, कुछ एक्सटेंशन के साथ इसका कोई लेना-देना नहीं है, जिनके पास C89 में अर्थ नहीं है। और वे विस्तार जो कि वेरिएबल घोषणापत्र के प्लेसमेंट को प्रतिबंधित नहीं करते हैं वे एक्सटेंशन के अंतर्गत हैं जो C89 का विरोध नहीं करते हैं।

ईमानदार होने के लिए, हर कोई सोचता है कि उसे "-स्टडी = सी 8 9" विकल्प की पहली नजर में पूरी तरह से सी 8 9 के अनुरूप होना चाहिए। लेकिन यह नहीं है समस्या के लिए, जो शुरुआत में सभी चर घोषित करते हैं, बेहतर या खराब है सिर्फ आदत की बात है।