2010-05-15 17 views
46

extern int n क्यों संकलित नहीं होता है जब एन घोषित किया जाता है (एक अलग फ़ाइल में) static int n, लेकिन int n घोषित करते समय काम करता है? (इन घोषणाओं में से दोनों फाइल दायरे में थे।)एक स्थिर चर के लिए बाहरी लिंक क्यों नहीं होगा?

असल में, int n फ़ाइल दायरे में क्यों static int n समान दायरे में नहीं है? क्या यह केवल बाहरी के संबंध में है? यदि हां, तो मुझे क्या पता चल रहा है?

उत्तर

97

static का पूरा और पूरा उद्देश्य यह घोषित करना है कि एक चर स्रोत फ़ाइल के लिए निजी है जिसे इसे में घोषित किया गया है। इस प्रकार, यह एक बाहरी से कनेक्शन को रोकने में ठीक से अपना काम कर रहा है।

ध्यान रखें फ़ाइल गुंजाइश चर परिभाषा के चार जायके देखते हैं कि:

  1. int blah = 0; - blah इस फाइल में परिभाषित और अन्य फ़ाइलों से पहुँचा जा सकता है। अन्य फाइलों में परिभाषाएं डुप्लीकेट हैं और त्रुटियों का कारण बनती हैं।
  2. extern int blah; - ब्लाह को कहीं और परिभाषित किया जाना चाहिए और इस फ़ाइल से संदर्भित किया जाना चाहिए।
  3. int blah; - यह FORTRAN COMMON का नैतिक समकक्ष है। आपके पास इनमें से किसी भी फाइल में हो सकता है, और वे सभी लिंकर द्वारा एक साझा int पर हल किए गए हैं। (*)
  4. static int blah; (वैकल्पिक रूप से प्रारंभकर्ता के साथ) - यह स्थिर है। यह इस फ़ाइल के लिए पूरी तरह से निजी है। यह अन्य फ़ाइलों में बाहरीों के लिए दृश्यमान नहीं है, और आपके पास कई अलग-अलग फाइलें हो सकती हैं जो सभी static TYPE blah; घोषित करती हैं, और वे सभी अलग-अलग हैं।

दर्शकों में शुद्धवादियों के लिए: 'फ़ाइल' = संकलन इकाई

ध्यान दें कि स्थिर अंदरूनी फ़ंक्शंस (फ़ाइल स्कोप पर नहीं) भी अधिक कसकर स्कॉप्ड हैं: यदि दो फ़ंक्शन static int bleh = 0; को उसी फ़ाइल में घोषित करते हैं, तो वे असंबद्ध हैं।

(*): आप में से उन लोगों के लिए परिचित नहीं हैं: सामान्य पैटर्न में, एक संकलन इकाई को वैश्विक चर परिभाषित करना होता है, और अन्य इसका संदर्भ दे सकते हैं। यह संकलन इकाई में 'रहता है'। यदि (3), ऊपर, कोई फ़ाइल (या सभी फाइलें) इसे परिभाषित नहीं करती हैं। यदि दो फाइलें int blah = 0; कहती हैं, तो लिंकर कई परिभाषाओं की शिकायत करेगा। यदि दो फाइलें int blah; कहती हैं तो लिंकर खुशी से एक वैश्विक int बनाता है और सभी कोड इसका संदर्भ लेता है।

+0

स्टोरेज विनिर्देशकों के संदर्भ में, 'int n' को किस प्रकार (फ़ाइल स्कोप में) कहा जाएगा? –

+0

@bmargulies: फ़ाइल दायरे पर, आपका मतलब है? क्योंकि फ़ंक्शन स्कोप पर, एक स्थैतिक var वह होता है जो फ़ंक्शन रिटर्न के बाद अपना मान बरकरार रखता है, और कक्षा के दायरे में, एक स्थिर सदस्य के पास सभी ऑब्जेक्ट्स के लिए एक एकल उदाहरण उपलब्ध होता है। – mingos

+0

संपादन द्वारा स्पष्ट, मुझे भरोसा है। – bmargulies

5

मानक सी में, फ़ंक्शन के बाहर घोषित चर के लिए दो स्कोप हैं। एक static चर केवल संकलन इकाई (यानी, फ़ाइल) के अंदर दिखाई देता है जिसने इसे घोषित किया है, और पूरे कार्यक्रम में गैर स्थैतिक चर दिखाई दे रहे हैं। एक extern घोषणा कहती है कि परिवर्तनीय का स्थान अभी तक ज्ञात नहीं है, लेकिन लिंकर द्वारा हल किया जाएगा; यह गैर स्थैतिक चर के साथ संगत है, लेकिन extern static सिर्फ पागल बात है!

बेशक, अभ्यास में इन दिनों अन्य दृश्यताएं हैं। विशेष रूप से, अब एक एकल स्रोत फ़ाइल और पूरे कार्यक्रम के बीच स्कोपिंग स्तर हैं; एक साझा साझा लाइब्रेरी का स्तर एक उपयोगी है (जीसीसी फ़ंक्शन विशेषताओं जैसे तंत्र के माध्यम से सेटटेबल)। लेकिन यह गैर स्थैतिक चर के विषय पर सिर्फ एक भिन्नता है; static वही व्याख्या करता है जो पहले था।

0

MSDN प्रलेखीकरण के अनुसार:

When modifying a variable, the static keyword specifies that the variable has static duration (it is allocated when the program begins and deallocated when the program ends) and initializes it to 0 unless another value is specified. When modifying a variable or function at file scope, the static keyword specifies that the variable or function has internal linkage (its name is not visible from outside the file in which it is declared).

http://msdn.microsoft.com/en-us/library/s1sb61xd(v=vs.80).aspx: जून 2013

1

iv.c: 2: 1: त्रुटि: घोषणा विनिर्देशक में एक से अधिक भंडारण वर्गों निर्वासन स्थिर पूर्णांक मैं; ^

यही वह है जो हम स्थिर चर को बाहर करने का प्रयास करते हैं। बाहरी स्थिर int घोषित करना; - घोषणापत्र फ्लोट int i के समान है; आप एक ही घोषणा में फ्लोट और int दिखाई नहीं दे सकते हैं? इसी तरह, आप एक ही घोषणा में बाहरी और स्थैतिक नहीं हो सकते हैं।

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