2010-03-27 22 views
15

में स्थिर चर कई सी और सी ++ के बीच किसी भी समारोह के बाहर static के रूप में घोषित एक चर के बीच कोई अंतर है। मैंने पढ़ा है कि static का अर्थ है फ़ाइल स्कोप और चर फ़ाइल के बाहर पहुंच योग्य नहीं होंगे। मैंने यह भी पढ़ा कि सी में, वैश्विक चर static हैं। तो क्या इसका मतलब है कि सी में वैश्विक चर को किसी अन्य फ़ाइल में एक्सेस नहीं किया जा सकता है?सी और सी ++

उत्तर

16

नहीं, इस संबंध में सी और सी ++ के बीच कोई अंतर नहीं है।

this SO answerstatic के बारे में सी प्रोग्राम में क्या मतलब है। सी ++ में कक्षा चर के लिए static के उपयोग से संबंधित कुछ अन्य अर्थ हैं (उदाहरण चर के बजाय)।

वैश्विक वार्स static जा रहा है के बारे में - केवल स्मृति आवंटन की दृष्टि से (वे, डेटा खंड पर आवंटित किए जाते हैं के रूप में सभी वैश्विक हैं)। दृश्यता की दृष्टि से:।

static int var; // can't be seen from outside files 
int var;   // can be seen from outside files (no 'static') 
+0

तो मैं सी में फ़ाइल के बाहर एक चर का उपयोग कैसे करूं? 'बाहरी '' स्थिर' अधिकार के साथ काम नहीं करेगा? हो सकता है कि मैं बहुत उलझन में हूं .. – Naveen

+0

@ नवीन: कोई समस्या नहीं है, * जब तक कि आपने इसे 'स्थिर' –

+0

ठीक घोषित नहीं किया है, तो दूसरे मामले में, चर 'var' के लिए स्टोरेज क्लास क्या होगा? क्या इसके लिए कोई नाम है या इसे वैश्विक चर कहा जाता है? – Naveen

7

वहाँ दो अवधारणाओं यहाँ "स्थिर लिंकेज (या गुंजाइश)" और स्थिर आवंटन "हैं

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

5

C और C++ एक ही हैं।

स्थैतिक दो अलग-अलग चीजें करता है।

फ़ंक्शन स्कोप के बाहर घोषित चर के लिए, यह चर के दृश्यता (लिंकेज) को बदलता है। वेरिएबल एक वैरिएबल वैरिएबल होगा क्योंकि यह फ़ंक्शन स्कोप के बाहर है। यदि यह स्थैतिक नहीं है, तो इसमें सार्वभौमिक संबंध (दृश्यता) होगी, इसलिए इसके साथ जुड़े किसी भी कोड को एक्सेस कर सकते हैं (उन्हें इसे बाहरी घोषित करना पड़ सकता है)। यदि चर एक फ़ंक्शन स्कोप से बाहर है और स्थिर है, तो यह अभी भी एक वैश्विक चर है कि यह हमेशा मौजूद है और उसका मान रखता है, लेकिन उसी संकलन इकाई (उस .c फ़ाइल और किसी भी .h के शामिल) के बाहर कोई कोड इसे एक्सेस नहीं कर सकता है।

फ़ंक्शन स्कोप के अंदर घोषित चर के लिए, स्थिर स्थान उस स्थान को बदलता है जहां चर संग्रहित होता है। यदि यह स्थिर नहीं है, तो यह एक स्वचालित चर होगा, जिसका अर्थ है कि यह गायब हो जाता है क्योंकि फ़ंक्शन निकलता है और फ़ंक्शन फिर से दर्ज होने पर अस्तित्व में आता है (ढेर पर)। जब आप फ़ंक्शन से बाहर निकलते हैं तो यह उसका मूल्य खो देता है। और फ़ंक्शन से बाहर निकलने के बाद भी इसके लिए कोई संदर्भ (पॉइंटर्स) अमान्य हैं। यदि फ़ंक्शन स्कोप के अंदर घोषित एक चर स्थिर है, तो यह इसे स्वचालित चर नहीं बनाता है बल्कि वैश्विक स्तर पर आवंटित किया जाता है। तो फ़ंक्शन से बाहर निकलने के बाद वेरिएबल मौजूद होगा और इस प्रकार फ़ंक्शन के इनवॉक्शंस में अपना मान रखेगा और फ़ंक्शन से बाहर निकलने के बाद भी इसके लिए कोई भी संदर्भ (पॉइंटर्स) मान्य होगा। ध्यान दें कि दोनों स्थितियों में चर का दायरा केवल उस फ़ंक्शन के भीतर है, इसलिए फ़ंक्शन स्कोप के बाहर से इसे सीधे एक्सेस करना संभव नहीं है (लेकिन केवल सहेजे गए संदर्भ के माध्यम से)।

वैरिएबल के लिए प्रारंभकर्ता (i.e. int foo = 5) चलाए जाने पर एक आखिरी चीज स्थिर होती है। उन सभी मामलों के लिए जहां आवंटन वैश्विक है (स्वचालित एक को छोड़कर हर मामले), प्रारंभकर्ता आपके प्रोग्राम के निष्पादन की शुरुआत में केवल एक बार चलाया जाता है। यह मुख्य() से पहले चलाया जाता है, इसलिए आप कुछ अनुमानित परिणाम प्राप्त नहीं कर सकते हैं यदि आपका प्रारंभकर्ता केवल स्थिर संख्या नहीं है लेकिन कुछ कोड चलाता है। स्वचालित मामले के लिए, प्रत्येक बार फ़ंक्शन दर्ज होने पर प्रारंभकर्ता चलाया जाता है, और इस मामले में यह मुख्य() दर्ज होने के बाद हमेशा होता है।

static के उपयोग से संकेत मिलता है "अनुवाद इकाई के लिए स्थानीय 'सी में हटाई गई है ++ (href =" http:

+0

क्या आप सुनिश्चित हैं कि फ़ंक्शन के अंदर स्थिर चर मुख्य() से पहले प्रारंभ हो जाएं? मैंने हमेशा सोचा कि उन्हें पहली बार समारोह कहा गया था, और यह भी है कि यहां जवाब क्या कहते हैं: http://stackoverflow.com/questions/246564/what-is-the-lifetime-of-a-static-variable -इन-एसी-फ़ंक्शन –

+0

उस थ्रेड में उत्तर C++ के लिए हैं। मुझे लगता है कि मेरी धारणा है कि सी और सी ++ ऐसा करते हैं, यह गलत है।कुछ दिख रहे हैं कि सी केवल स्थिर प्रारंभकर्ताओं की अनुमति देता है और वे संकलन समय पर भरे हुए हैं, रनटाइम नहीं। तो यह मेरे क्रेडिट के लिए मुख्य() से पहले है। लेकिन मैं बाकी के बारे में गलत था, सी ++ यह अलग-अलग करता है और इसलिए आपके द्वारा डाले गए लिंक के अनुसार सभी मामलों को समझना चाहिए। –

1

मैं Static variables in C and C++

निम्नलिखित टिप्पणी दक्षिणी आतिथ्य के जवाब में जोड़ना चाहते हैं // rads.stackoverflow.com/amzn/click/0201700735 "सी ++ प्रोग्रामिंग भाषा: विशेष संस्करण, परिशिष्ट बी.2.3, अस्वीकृत विशेषताएं)।

इसके बजाय आप अनाम नामस्थान उपयोग करना चाहिए:

static int reply = 42; // deprecated 

namespace { 
    int reply1 = 42; // The C++ way 
} 

जैसा कि पहले ही दक्षिणी आतिथ्य से कहा, वैश्विक वस्तुओं के प्रारंभ के आदेश अपरिभाषित है। उस स्थिति में, आपको href = "http://en.wikipedia.org/wiki/Singleton_pattern#C.2B.2B", सिंगलटन पैटर्न का उपयोग करने पर विचार करना चाहिए।

अद्यतन: ", आदेश परिभाषित किया गया है प्रति-अनुवाद इकाई ..."

: GMAN मेरा उत्तर टिप्पणी की यह वास्तव में मेरे मन फिसल गया, तो मैं में सी ++ प्रोग्रामिंग भाषा इसे ऊपर देखा।

धारा 9.4.1 में, गैर-स्थानीय चर का प्रारंभ, प्रो Stroustrup चलता है कि "एक संदर्भ फ़ंक्शन एक वैश्विक चर के लिए एक अच्छा विकल्प है":

int& use_count() 
{ 
     static int uc = 0; 
     return uc; 
} 

"एक कॉल use_count() को अब एक वैश्विक चर है कि इसके पहले प्रयोग में आरंभ नहीं हो जाता के रूप में कार्य उदाहरण के लिए:। "

void f() 
{ 
     std::cout << ++use_count() << '\n'; 
} 

मेरी समझ में, यह बहुत सिंगलटन पैटर्न के समान है।

जीएमन ने आगे टिप्पणी की: "हमें इन वस्तुओं को एक बनाने के लिए हमारी क्षमता को सीमित करने की आवश्यकता है, और इसके लिए वैश्विक पहुंच प्रदान करें।" क्या किसी के लिए सीमित समस्या वास्तव में किसी भी चीज़ से संबंधित है? हम विश्व स्तर पर एक आवश्यकता हो सकती है, लेकिन जो कहने के लिए हम अन्य स्थानों में यह नहीं करना चाहती है "

सिंगलटन से कुछ उद्धरण (127) (गामा एट अल, डिजाइन पैटर्न):

"? सिंगलटन पैटर्न है वैश्विक चर पर सुधार। यह वैश्विक चर कि एकमात्र उदाहरणों की दुकान के साथ नाम अंतरिक्ष प्रदूषण टाल। "

" पैटर्न आसान अपना मन बदल और सिंगलटन वर्ग के एक से अधिक उदाहरण अनुमति देने के लिए बनाता है। "

Singletons में प्रारंभ कर रहे हैं । आदेश वे पहली बार उपयोग किया जाता है

हर्ब Sutter, आंद्रेई Alexandrescu, सी ++ में मानक कोडिंग, मद 10 का कहना है:

"साझा डेटा, विशेष रूप से वैश्विक डेटा से बचें।"

इसलिए मैं अक्सर उपयोग वैश्विक डेटा से बचने के लिए सिंगलेट्स। लेकिन निश्चित रूप से, जैसा कि सबकुछ अतिसंवेदनशील है, यह सिंगलटन पैटर्न का अत्यधिक उपयोग हो सकता है। (Johshua Kerievsky "पैटर्न को पुनर्रचना" अपनी पुस्तक में इस "Singletonitis" कहता है।)

अद्यतन 2:

(क्षमा करें, लेकिन मैं नहीं टिप्पणी लिख सकते हैं, इसलिए इस अद्यतन।)

जैल्फ ने अपनी टिप्पणी में लिखा: "सिंगलटन पैटर्न के बारे में उन्होंने लिखा जब चार का गिरोह कुछ गैरकानूनी धूम्रपान कर रहा था।"

जाहिर है, अन्य सी ++ डेवलपर्स ने भी दिलचस्प पदार्थों को धूम्रपान किया। उदाहरण के लिए, हर्ब सटर (उन्होंने दूसरे सी ++ मानक, सी ++ 0x के विकास के दौरान आईएसओ सी ++ मानकों की समिति के सचिव और अध्यक्ष के रूप में एक दशक से अधिक समय तक कार्य किया, और माइक्रोसॉफ्ट में सी ++/सीएलआई के मुख्य वास्तुकार के रूप में कार्य किया। हर्ब वर्तमान में है माइक्रोसॉफ्ट प्लेटफार्मों के लिए प्रिज्म मेमोरी मॉडल के डिजाइनर और समानांतर प्रोग्रामिंग के लिए विज़ुअल सी ++ के लिए कंसूर एक्सटेंशन), ​​सी ++ कोडिंग मानकों में लिखा गया है, आइटम 21:

"जब आपको ऐसे (नेमस्पेस स्तर) चर की आवश्यकता होती है जो उस पर निर्भर हो सकती है दूसरा, सिंगलटन डिज़ाइन पैटर्न पर विचार करें; ध्यान से उपयोग किया जाता है, यह सुनिश्चित करके यह निर्भर करता है कि किसी ऑब्जेक्ट को पहली पहुंच पर शुरू किया गया है। फिर भी, सिंगलटन भेड़ के कपड़ों में एक वैश्विक चर है, और आपसी या चक्रीय निर्भरताओं से टूट जाता है। "

तो, वैश्विक डेटा से बचें, यदि आप कर सकते हैं। लेकिन अगर आपको अलग-अलग अनुवाद इकाइयों में वैश्विक डेटा का उपयोग करना है, तो सिंगलटन को एक विशिष्ट प्रारंभिक अनुक्रम लागू करने के लिए एक स्वीकार्य समाधान होना चाहिए।

ध्यान दें कि जावा भाषा में वैश्विक डेटा भी मौजूद नहीं है। जाहिर है, सिंगलटन डिजाइन पैटर्न के उपयोग से वैश्विक डेटा को प्रतिस्थापित/नकल किया जाता है।

(के लिए मैं एक जावा टीम के साथ मेरी dayjob में काम कर रहा हूँ, मैं अपने सी ++ जावा कार्यक्रमों के साथ कार्यक्रमों की एक अधिक से अधिक समानता के लिए प्रयास करते हैं। उदाहरण के लिए, हर वर्ग का अपना स्रोत फ़ाइल/अनुवाद इकाई में स्थित है।)

+0

ऑर्डर को प्रति-अनुवाद इकाई परिभाषित किया गया है, इसके लिए यह क्या लायक है। लेकिन मुझे आशा है कि आप देखेंगे कि सिंगलटन पैटर्न समाधान नहीं है। "इकाइयों में प्रारंभिक आदेश अनिर्दिष्ट है" -> "हमें इन वस्तुओं को एक बनाने के लिए हमारी क्षमता को सीमित करने की आवश्यकता है, और इसके लिए वैश्विक पहुंच प्रदान करें।" क्या किसी के लिए सीमित समस्या वास्तव में किसी भी चीज़ से संबंधित है? हमें एक * वैश्विक रूप से * की आवश्यकता हो सकती है, लेकिन कौन कहता है कि हम इसे अन्य स्थानों में नहीं चाहते हैं? – GManNickG

+2

@edit: सिंगलेट्स वैश्विक डेटा हैं, भले ही आप इसे कैसे तैयार करते हैं। अनावश्यक प्रतिबंध भी ले सकते हैं और वैश्विक रैपर बना सकते हैं। http://jalf.dk/blog/2010/03/singletons-solving-problems-you-didnt-now-you-never-had-since-1995/ – GManNickG

+1

गामा एट अल से आपका उद्धरण कैसे समझ में आता है? ग्लोबल इंस्टेंस सिंगलटन की तुलना में नामस्थान को और प्रदूषित नहीं करते हैं। (उदाहरण के रूप में 'std :: cout' ले लो। एक वैश्विक उदाहरण, जो std नेमस्पेस में दिखाई देता है। आपका' f' फ़ंक्शन बेहतर कैसे होता है? यह नामस्थान में दिखाई देता है जिसमें इसे घोषित किया जाता है। दूसरे भाग के लिए, नहीं, सिंगलेट्स इसे आपके दिमाग को बदलने के लिए ** बहुत कठिन * बनाते हैं। आपका पूरा कोडबेस getInstance() कॉल या स्थैतिक डेटा की निहित पहुंच के साथ बिखरा हुआ है। मैं अपने निष्कर्ष से खड़ा हूं: चार के गिरोह ने कुछ गैरकानूनी धूम्रपान किया था जब उन्होंने लिखा था सिंगलटन पैटर्न। – jalf

0

वास्तव में आपके प्रश्न का सीधा जवाब नहीं है, लेकिन यदि आप सी और सी ++ दोनों का उपयोग करते हैं तो देखने के लिए कुछ निकटता से संबंधित है।

सी ++ में, सी के विपरीत, वैश्विक चर जो "कॉन्स्ट" घोषित किए जाते हैं, अनुवाद इकाई के लिए स्थानीय रूप से स्थानीय हैं, एएस आईएफ "स्थैतिक" का उपयोग किया गया था।

उदाहरण:

// file A 
extern const int glob; 

// file B 
const int glob = 42; 

यदि आप एक सी संकलक लेकिन एक सी ++ संकलक के साथ नहीं प्रयोग कर रहे हैं काम करेंगे। सी ++ में, फ़ाइल बी में ग्लोब चर का उपयोग फ़ाइल ए से नहीं किया जा सकता है और लिंकर "अनसुलझा संदर्भ" त्रुटि उत्पन्न करेगा।