2010-06-04 19 views
21

में स्टेटिक कार्य करता है और चर का उपयोग करने के लिए मैं एक सी कार्यक्रम का निर्माण करने के रूप में मैं देख रहा हूँ यह है मानक तरीका सीकारण सी

में, एक फ़ाइल में चर के लिए सीमित दायरे के रूप में static कीवर्ड के उपयोग के बारे में चिंता करने के लिए:

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

मैं static के रूप में एक gobal घोषित करने के लिए दो कारण देखते हैं, अगर चर ज फ़ाइल में प्रकाशित नहीं है वैसे भी:

  • एक पठनीयता के लिए है। अपने आप सहित भविष्य के पाठकों को सूचित करें कि एक चर को किसी अन्य फ़ाइल में एक्सेस नहीं किया गया है।
  • दूसरा दूसरा चर फ़ाइल को extern के रूप में पुनर्विक्रय करने से रोकने के लिए है। मुझे लगता है कि लिंकर एक चर को नापसंद करेगा extern और static दोनों। (मैं एक फ़ाइल extern के रूप में किसी अन्य के स्वामित्व एक चर redeclaring के विचार नापसंद करते हैं, यह ठीक बात है?)

किसी भी अन्य कारण?

static फ़ंक्शंस के लिए चला जाता है। यदि प्रोटोटाइप एच फ़ाइल में प्रकाशित नहीं होता है, तो अन्य फाइलें फ़ंक्शन का उपयोग नहीं कर सकती हैं, तो इसे static क्यों परिभाषित करें? मैं वही दो कारण देख सकता हूं, लेकिन नहीं।

+0

छह साल बाद, अब मुझे पता है कि 'स्थैतिक' गुंजाइश को सीमित नहीं करता है, यह आंतरिक जुड़ाव देता है। यह समान है, यदि आप एक अनुवाद इकाई को एक दायरे के रूप में मानते हैं, लेकिन सही शब्द नहीं है। – Gauthier

उत्तर

23

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

extern के रूप में एक static चर पुनर्परिभाषित असंभव है, लेकिन संकलक (हमेशा की तरह) तुम अपने आप को फांसी के लिए पर्याप्त रस्सी दे देंगे।

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

वैश्विक चर शायद ही कभी हेडर फाइल में दिखाई देते हैं, लेकिन वे extern घोषित किया जाना चाहिए जब वे करते हैं। यदि नहीं, तो आपके कंपाइलर के आधार पर, आप जोखिम देते हैं कि प्रत्येक स्रोत फ़ाइल जिसमें हेडर शामिल है, वह चर की अपनी प्रति घोषित करेगा: सबसे अच्छा यह एक लिंक विफलता (गुणा परिभाषित प्रतीक) और overshadowing के सबसे भ्रमित मामलों में सबसे खराब होगा।

+1

दिलचस्प। मैं समझता हूं कि यह "हेडर फ़ाइल में बाहरी वैश्विक" को अभी भी एक सी फ़ाइल में परिभाषा की आवश्यकता है, क्योंकि एच फ़ाइल में बाहरी इसे केवल घोषणा करता है। – Gauthier

+1

आप सही हैं। – crazyscot

7

फ़ाइल स्तर पर एक चर static घोषित करके (static फ़ंक्शन के भीतर एक अलग अर्थ है) आप अन्य इकाइयों को इसे एक्सेस करने के लिए मना करते हैं, उदा। यदि आप किसी अन्य इकाई के अंदर परिवर्तनीय उपयोग करने की कोशिश करते हैं (extern के साथ घोषित), तो लिंकर को यह प्रतीक नहीं मिलेगा।

+0

यह उल्लेख किया गया है कि मैंने दो कारणों में से एक है: "दूसरी बात यह है कि दूसरी सी फाइल को प्रतीत होता है कि इसे 'बाहरी' के रूप में फिर से चलाकर प्रतीत होता है। और मैंने इस तरह की प्रथा की गुणवत्ता के बारे में सोचा? – Gauthier

+0

@ गौथियर इसलिए आपकी पोस्ट में आंतरिक संघर्ष है तो – qrdl

+2

आईएमओ, 'स्थिर' का अर्थ तीनों प्रसिद्ध ज्ञात उपयोगों (फ़ाइल चर, फ़ंक्शन वेरिएबल, फ़ंक्शन) में समान अर्थ है और यह है: "इसमें सीमित दायरा है और इसमें स्थिरता है कार्यक्रम निष्पादन के दौरान पता "। – Gauthier

1

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

6

जब आप स्थिर फ़ंक्शन को कॉल करते हैं तो फ़ंक्शन पर कॉल "नज़दीकी कॉल" है और सिद्धांत रूप में यह "दूर कॉल" से बेहतर प्रदर्शन करता है। आप अधिक जानकारी के लिए Google कर सकते हैं। This जो मैंने एक साधारण Google खोज के साथ पाया है।

+0

भी दिलचस्प है, हालांकि मंच निर्भर है (मेरे लक्ष्य में केवल एक कॉल निर्देश पूर्ण है, और दूर/पास नहीं है)। – Gauthier

+0

उदा। जीसीसी कई प्लेटफॉर्म पर स्थिर कार्यों के लिए कॉलिंग कन्वेंशन (कुछ तेज़ी से) स्विच कर सकता है। – nos

-1

स्थैतिक का मेरा पसंदीदा उपयोग उन विधियों को स्टोर करने में सक्षम है जो मुझे उपयोग करने के लिए इंजेक्ट करने या बनाने के लिए नहीं हैं, जिस तरह से मैं इसे देखता हूं, निजी स्टेटिक तरीके हमेशा उपयोगी होते हैं, जहां सार्वजनिक स्थिर आपको कुछ रखना होता है यह सोचने में अधिक समय है कि आप क्या कर रहे हैं, यह जानने के लिए कि क्या पागलपन को परिभाषित किया गया है, अपने स्वयं को बहुत अधिक रस्सी प्राप्त करना और गलती से स्वयं को लटका देना!

मुझे अपनी अधिकांश परियोजनाओं के लिए हेल्पर कक्षाओं के लिए एक फ़ोल्डर रखना पसंद है जो मुख्य रूप से फ्लाई पर चीजों को जल्दी और कुशलतापूर्वक करने के लिए स्थिर तरीकों से युक्त होता है, कोई वस्तु नहीं होती है!

+2

प्रश्न सी के बारे में है, सी ++ नहीं। सी में कोई कक्षाएं, कोई विधि नहीं, और कोई निजी सदस्य नहीं हैं। इसके अलावा, सी ++ में स्थिर कार्यों और स्थिर तरीकों में एक अंतर है। –

+1

ओह! मुझे एहसास है कि मैं निश्चित रूप से प्रश्न को गलत तरीके से पढ़ता हूं। –

0

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

यदि आप इसे स्थिर बनाये बिना फ़ाइल एसी में फ़ंक्शन foo() लिखते हैं, और फ़ाइल बीसी में फ़ंक्शन foo() स्थिर बनाते हैं, तो लिंकर शिकायत कर सकता है, लेकिन यदि ऐसा नहीं होता है, तो सभी को foo() एक ही समारोह को बुलाएगा। अपने कोड को मजेदार डिबगिंग की अपेक्षा करें।

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