2009-12-08 50 views
7

कुछ बार हमें स्थिर चर को पूर्व-घोषित करने की आवश्यकता होती है और फिर इसका उपयोग करें। लेकिन इस घोषणा का परिवर्तनीय नाम गलत हो सकता है, और संकलक इसे पहचान नहीं सकता है, ओह!एक स्थैतिक चर घोषित कैसे करें लेकिन इसे परिभाषित न करें

उदाहरण:

/* lots of codes */ 
static some_type some_name; /* pre-declaration */ 
          /* but it may define "some_name" */ 
/* use some_name */ 

/* lots of codes */ 

static some_type someName = initialization; /* definition */ 
/* use someName */ 

/* lots of codes */ 

"some_name" और "SomeName" कर रहे हैं अलग, हम पर शुरू एक गलत चर का उपयोग करें। यदि पूर्व-घोषणा विवरण किसी भी चीज़ को परिभाषित नहीं करता है, तो संकलक गलती का पता लगाएगा।

तो, एक स्थैतिक चर घोषित कैसे करें लेकिन इसे परिभाषित नहीं करें? मैं प्री-घोषणा को नए तरीके से कैसे बदल सकता हूं जो संकलक गलत नामों का पता लगा सकता है?

+4

स्थैतिक मतलब संकलन समय पर लोड किया गया है। आप इसे क्यों शुरू नहीं करना चाहते हैं? – Woot4Moo

+1

Woot4Moo: सी में एक वैश्विक चर 'static' बनाना मतलब है कि यह वर्तमान "संकलन इकाई" के बाहर दिखाई नहीं देता है, आमतौर पर एक .c फ़ाइल और उसके सभी शीर्षलेख। सभी वैश्विक चर जो 'extern'd नहीं हैं संकलन-समय पर स्थान आवंटित किए जाते हैं। – Anton

उत्तर

9

gcc मामले आप का वर्णन किया है में एक चेतावनी दे देंगे आप वर्तमान में क्या कर रहे हैं क्या है, लेकिन संकलक चेतावनी को अनदेखा न करें;)

संपादित करें:

आपके अपडेट किए गए प्रश्न के साथ: नहीं, मुझे विश्वास नहीं है कि एक स्थैतिक चर घोषित करने का कोई तरीका है (इसे परिभाषित किए बिना)।

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

+0

"कुछ नाम" का भी उपयोग किया जा रहा है, मैंने अपनी पोस्ट को थोड़ा बदल दिया है, धन्यवाद। –

8
static some_type some_name; /*definition */ 

स्थैतिक चर कुछ_नाम 0 से शुरू किया गया है; यह परिभाषा है, सिर्फ एक घोषणा नहीं।

आईएमओ, एक स्थिर चर को बाहरी विनिर्देशक का उपयोग करके सी में घोषित नहीं किया जा सकता क्योंकि इसकी लिंक हमेशा आंतरिक होती है।

./x.c:3010: warning: 'someName' defined but not used 

समाधान::

+1

मुझे नहीं लगता कि आप "आईएमओ" का उपयोग कर रहे हैं।यह एक राय की तरह नहीं लगता है। –

+1

यह _is_ Prasoon की राय; यह मानक के साथ भी संरेखित है, इसलिए उनकी राय सही है (मानक के अनुसार)। –

0

क्या आपको चर को पूर्व घोषित करने की आवश्यकता है? यदि नहीं, तो प्रारंभिक घोषणा को केवल घोषणा पर रखें। यदि आपका प्रारंभकर्ता स्थिर नहीं है (जिसके लिए सी ++, सी नहीं, आईआईआरसी की आवश्यकता होगी), तो मैं समझ सकता हूं कि इसका उपयोग करने वाले कुछ कार्यों से पहले आपको इसे पूर्व-घोषित करने की आवश्यकता क्यों है। लेकिन फिर प्रारंभकर्ता के लिए आपको जो भी चीज चाहिए, उसे पहले घोषित किया जा सकता है।

तो प्रत्येक फ़ाइल के शीर्ष पर अपने निरंतर defs और स्थिर चर डाल दें, इसलिए स्थैतिक के लिए आपका प्रारंभकर्ता स्थिरांक के ठीक बाद आ सकता है। फिर आपको एक अलग प्रारंभिक रेखा की आवश्यकता नहीं है।

किसी भी अन्य मामले में, कैफ का अधिकार: यह आपके कोड को केवल चेतावनियों का लाभ प्राप्त करने के लिए जीसीसी के साथ संकलित करने के लायक हो सकता है। मैंने सी ++ में एमएफसी जीयूआई के लिए जी ++ के लिए ऐसा किया है। (संकलित करें, दौड़ें नहीं!)

AFAIK C में कमजोर परिभाषा लिखने का कोई तरीका नहीं है जो बाद में प्रारंभकर्ता के साथ परिभाषा नहीं है, तो त्रुटि उत्पन्न होगी। हमेशा एक अंतर्निहित 0 होता है, क्योंकि चर बीएसएस अनुभाग में जाता है।

-1

यदि मैं आपकी समस्या को समझता हूं तो शायद आपको इसका सही सामना नहीं करना पड़ेगा।

क्या आप extern SomeType someVar_; के साथ बेहतर नहीं होंगे जो आपके प्रोग्राम से कहता है, मुझे पता है कि यह चर ज्ञात होगा, लेकिन मैं आपको यह बताना नहीं चाहता कि अब यह क्या है।

इसलिए, एक अलग फाइल में अपने चर घोषणा कर सकते हैं

static SomeType SomeVar_;

कहना आपकी फ़ाइल में, डाल

extern SomeType SomeVar_

और आरंभीकरण जहां भी आप चाहते डाल से।

+1

इससे लिंकर त्रुटि हो जाएगी, क्योंकि 'स्थिर' परिभाषा में आंतरिक संबंध है और फ़ाइल द्वारा उस तक नहीं पहुंचा जा सकता है जहां इसे 'बाहरी' का उपयोग करके घोषित किया जाता है। –

2

एक छोटी सी पृष्ठभूमि:

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

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

सुझाव:

तुम सच में संकलन समय पर चर के मूल्य को नहीं जानते हैं, तो आप यह गतिशील अपने प्रारंभ समारोह में आवंटित करने चाहिए।

static some_type some_variable; /* = 0 by default */ 

/* some code */ 

void MyInitializations() 
{ 
    some_variable = some_value; 
} 

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

हैडर:

extern some_type some_variable; 

स्रोत फ़ाइल 1:

void UseSomeVariable() 
{ 
    x = some_variable; 
} 

स्रोत फ़ाइल 2:

some_type some_variable = some_value; 

/* possible also uses some_variable */ 

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

3

सी भाषा में आंतरिक संबंध के साथ एक वस्तु के एक गैर-परिभाषित घोषणा (यानी "अपनी शब्दावली में पूर्व-घोषित") बनाना संभव नहीं है।

जितना करीब आप इसे प्राप्त कर सकते हैं टेटेटिव परिभाषा है, जो आपके उदाहरण में है। लेकिन एक टाइपो टेंटेटिव डिफेंस के मामले में एक स्वतंत्र परिभाषा उत्पन्न होगी, न कि एक लिंकर त्रुटि।

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