निम्नलिखित कोड का आउटपुट 0 है।

int account=2;

int main()
{
    static int account;
    printf("%d",account);
    return 0;
}

इसने वैश्विक चर पर स्थिर चर क्यों चुना? क्योंकि मैं जो समझता हूं वह यह है कि वैश्विक और स्थिर चर दोनों ढेर में संग्रहीत होते हैं, न कि फ़ंक्शन स्टैक में, है ना? तो यह किस विधि का उपयोग दूसरे के ऊपर एक का चयन करने के लिए करता है?

-1
user7015283 12 सितंबर 2018, 18:20

5 जवाब

सबसे बढ़िया उत्तर

यदि एक से अधिक क्षेत्रों में एक ही नाम के साथ कई चर मौजूद हैं, तो अंतरतम दायरे में से एक वह है जो पहुंच योग्य है। उच्च दायरे में चर छिपे हुए हैं।

इस मामले में आपने account को main में परिभाषित किया है। यह फ़ाइल दायरे में घोषित account नाम के वेरिएबल को छुपाता है। तथ्य यह है कि main के अंदर का आंतरिक चर static घोषित किया गया है, इससे कोई फर्क नहीं पड़ता।

जबकि स्थानीय चर पर static घोषणा का अर्थ है कि यह आमतौर पर एक वैश्विक चर के रूप में उसी स्थान पर संग्रहीत किया जाता है, जिसका कोई असर नहीं होता है, जब नाम समान होते हैं।

26
dbush 12 सितंबर 2018, 22:44

इस छोटे से आत्म-व्याख्या कार्यक्रम पर विचार करें:

#include <stdio.h>

int bar = 123;     // global variable, can be accessed from other source files

static int blark;  // global variable, but can be accessed only in the same
                   // source file

void foo()
{
  static int bar;  // static variable : will retain it's value from
                   // one call of foo to the next
                   // most compilers will warn here:
                   // warning  declaration of 'bar' hides global declaration

  printf("foo() : bar = %d\n", bar);  // won't use the global bar but the
                                      // local static bar
  bar++;
}

void quork()
{
  int bar = 777;   // local variable exists only during the execution of quork
                   // most compilers will warn here as well:
                   // warning  declaration of 'bar' hides global declaration

  printf("quork() : bar = %d\n", bar);  // won't use the global bar but the
                                        // local bar
  bar++;
}

int main() {
  foo();
  foo();
  printf("main() 1 : bar = %d\n", bar);
  bar++;
  quork();
  quork();
  foo();
  printf("main() 2 : bar = %d\n", bar);
  printf("blark = %d\n", blark);
}

आउटपुट:

foo() : bar = 0
foo() : bar = 1
main() 1 : bar = 123
quork() : bar = 777
quork() : bar = 777
foo() : bar = 2
main() 2 : bar = 124
blark = 0
7
Jabberwocky 5 नवम्बर 2018, 17:04

भविष्य के पाठकों के लिए स्पष्ट करने के लिए, वैश्विक और स्थिर चर ढेर या ढेर स्मृति में संग्रहीत नहीं होते हैं। https://www.geeksforgeeks.org/memory-layout-of-c -कार्यक्रम/

वे या तो आरंभिक डेटा या अप्रारंभीकृत डेटा में संग्रहीत किए जाएंगे।

यहां मुख्य प्रश्न नहीं है, जिसका उत्तर डबश द्वारा दिया गया था, लेकिन यह मूल प्रश्न में एक गलतफहमी है।

3
Bwebb 31 अक्टूबर 2018, 22:55

संक्षिप्त उत्तर: एनकैप्सुलेशन।

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

static फ़ाइल स्तर पर परिभाषित चरों का प्रोग्राम जीवनकाल होता है और संकलन इकाई< /a> दृश्यता। इसका मतलब है कि .c फ़ाइल में सभी फ़ंक्शन वेरिएबल को एक्सेस/संशोधित कर सकते हैं, लेकिन अन्य .c फ़ाइलें वेरिएबल के बारे में नहीं जानती हैं। यह सुपर यह सुनिश्चित करने के लिए उपयोगी है कि एक संकलन इकाई के साथ कार्यों में उपयोग किए जाने वाले चर अन्य संकलन इकाइयों में चर के साथ गलती से लिंक नहीं होते हैं। व्यक्तिगत रूप से, मैं अत्यधिक अनुशंसा करता हूं कि सभी फ़ाइल चर डिफ़ॉल्ट रूप से स्थिर हों। केवल static विनिर्देशक को हटा दें यदि आप वास्तव में किसी अन्य संकलन इकाई तक पहुंच प्राप्त करना चाहते हैं (हालांकि गेटर फ़ंक्शन सुरक्षित हो सकता है)

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

स्थिर चरों के साथ वास्तव में एक महत्वपूर्ण अंतर यह है कि वे डिफ़ॉल्ट रूप से शून्य से आरंभिक होते हैं। यह c में सभी अन्य वेरिएबल से अलग है, और यही कारण है कि आपका प्रोग्राम मान 0 प्रिंट करता है। अक्सर छोटे प्रोग्राम के साथ हमें अंतर दिखाई नहीं देता है क्योंकि स्टैक अभी तक वेरिएबल के साथ प्रदूषित नहीं हुआ है , लेकिन यह आकार के किसी भी कार्यक्रम के लिए महत्वपूर्ण हो जाता है।

इसके लिए सबसे आम उपयोग जो मैंने देखा है वह है एक बार के आरंभीकरण को एक दायरे में के भीतर सक्षम करना। वे pthread_mutex_t जैसे सिंक्रोनाइज़ेशन प्रिमिटिव के लिए भी बेहद उपयोगी हैं। एक बार मैंने फंक्शन-स्कोप स्टैटिक वेरिएबल वाली स्टेट-मशीन भी लागू की थी।

एक उदाहरण:

int started;//oops, anybody in the entire program can change this value, especially with such a common name!
static int lastCall;

int callCount(void)
{
    // This is default-initialized to 0
    static int functionStaticVariable;

    //Increment each time I'm called
    ++functionStaticVariable;

    //tell the outside world that I'm the one who was called last
    lastCall = 1;

    //return (a copy of) my internal state.
    return functionStaticVariable;
}

char *getSharedMemory(unsigned int bytes)
{
    // Here I cannot see functionStaticVariable, but I can see globalVariable
    //functionStaticVariable++; // this would cause a compilation failure

    // static pointer is default-initialized to zero (i.e. NULL)
    static char *sharedMemory;
    if(sharedMemory == 0)
    {
        // This block only executes once, the first time the function is called.
        // Actually this is a nice side-effect because it means if the function is never called we don't clutter the stack with unused memory
        // Although we will probably never free this memory
        sharedMemory = (char *)malloc(bytes);
    }

    // tell the outside world that this function has been called
    lastCall = 2;//valid

    //Woah, this is such a bad idea, but actually does _not_ return memory that gets invalidated
    return sharedMemory;
}

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

मैं गुप्त रूप से चाहता हूं कि सभी सी ++ प्रोग्रामर अच्छे सी इनकैप्सुलेशन सीखें, क्योंकि वास्तव में भाषा वास्तव में इसे प्रोत्साहित करती है। आप केवल एक संकलन इकाई में एक दूसरे के साथ संवाद करने के लिए आवश्यक कार्यों को रखकर एक अविश्वसनीय राशि कर सकते हैं। गैर-ओओपी भाषा में, यह बहुत शक्तिशाली हो सकता है।

स्थिर और बाहरी का पूरा विवरण https://en.cppreference.com/w द्वारा वर्णित है /c/भाषा/भंडारण_अवधि.

2
xaviersjs 6 नवम्बर 2018, 11:11

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

0
rioted 6 नवम्बर 2018, 18:17