2015-06-01 4 views
6

मैं जानना चाहता हूं कि वास्तव में हुड के नीचे क्या चल रहा है, कैसे कंपाइलर स्थिर चर का व्यवहार करता है। ऑटो वैरिएबल के विपरीत, स्थिर चर का मान ब्लॉक के अंत के बाद भी जारी रहता है लेकिन वास्तव में कंपाइलर्स इसे कैसे संभालते हैं?जब हम स्थैतिक चर घोषित करते हैं तो वास्तव में कंपाइलर क्या करता है?

+0

तुम्हारा मतलब है, स्मृति की किस तरह संभवतः एक कंप्यूटर है कि एक ब्लॉक के दायरे से बाहर अपने मूल्यों को धारण में मौजूद हो सकता? –

+3

एक 'स्थिर 'चर केवल एक वैश्विक चर है जिसमें सीमित दायरा है। – user3386109

+0

इसके अलावा, आप कुछ टेस्ट कोड लिख सकते हैं और 'मानचित्र' फ़ाइल को स्वयं देख सकते हैं –

उत्तर

7

स्टैक पर जाने वाले स्थानीय चर के विपरीत, स्थिर डेटा को विशेष डेटा सेगमेंट में रखा जाता है। आपका स्थैतिक चर किस खंड पर निर्भर करता है, इस पर निर्भर करता है कि वे 0 प्रारंभिक हैं या नहीं। 0 प्रारंभिक स्थिर डेटा में जाता है .BSS (प्रतीक द्वारा प्रारंभ किया गया ब्लॉक), गैर 0 प्रारंभिक डेटा में चला जाता है। DATA

यदि आप निष्पादन योग्य फ़ाइलों के भीतर विभिन्न सेगमेंट के बारे में और जानना चाहते हैं, तो this विकिपीडिया प्रविष्टि एक अच्छा प्रारंभिक बिंदु है। मैं कंप्यूटर सिस्टम में अध्याय 7 की अत्यधिक अनुशंसा करता हूं: रैंडल ई। ब्रायंट और डेविड आर ओ'हैलरॉन द्वारा एक प्रोग्रामर का परिप्रेक्ष्य

मैं यहां एक विशेष परिदृश्य का वर्णन कर रहा हूं। आपको यह ध्यान रखना होगा कि विवरण एक वास्तुकला से दूसरे में भिन्न होंगे, एक ओएस से दूसरे में, इतने पर और आगे। हालांकि, निष्पादन योग्य फ़ाइलों का सामान्य लेआउट वर्णित है। वास्तव में रोमांचक सामान!

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

लेखक कृपया मुझसे पूछा स्पष्ट करने के लिए:

.bss 0 प्रारंभ चर और गैर 0 .data के लिए शुरू में विभाजित करने की बात क्या है?

धारा 7.4 से

कंप्यूटर सिस्टम्स में: एक प्रोग्रामर परिप्रेक्ष्य.BSS खंड पर:

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

और, Wikipedia से:

आमतौर पर केवल .BSS अनुभाग की लंबाई, लेकिन कोई डेटा, वस्तु फ़ाइल में संग्रहित है। कार्यक्रम लोडर जब यह प्रोग्राम लोड करता है तो बीएसएस अनुभाग के लिए स्मृति आवंटित करता है और प्रारंभ करता है।

संक्षेप में: यह स्मृति को बचाने के लिए एक तंत्र है।

+0

यह सुंदर है स्पष्ट है कि हम रन टाइम पर हमारे स्थैतिक चर के मूल्य को बदल सकते हैं तो प्रारंभिक चर को .bss में विभाजित करने और .data को अनियमित करने का क्या मतलब है? चूंकि वे दोनों रीड-राइट मेमोरी सेगमेंट हैं। –

+0

कृपया उत्तर में मेरे नवीनतम संपादन का संदर्भ लें। उम्मीद है कि यह आपके लिए स्पष्ट करता है। –

+0

धन्यवाद, मुझे यह मिला है –

3

विशिष्ट सी कंपाइलर्स असेंबली आउटपुट उत्पन्न करते हैं जो स्मृति के चार "खंड" बनाता है। लिंकर/लोडर आम तौर पर उसी अनुभाग के साथ लेबल की गई विभिन्न वस्तुओं को एक साथ जोड़ता है क्योंकि यह प्रोग्राम को मेमोरी में लोड करता है। सबसे आम वर्ग हैं:

"टेक्स्ट": यह वास्तविक प्रोग्राम कोड है। इसे केवल पढ़ने के लिए माना जाता है (कुछ मशीनों पर लिंकर/लोडर इसे रोम में रख सकता है, उदाहरण के लिए)।

"डेटा": यह केवल रैम का एक आवंटित क्षेत्र है, जिसमें प्रारंभिक मान निष्पादन योग्य फ़ाइल से कॉपी किए गए हैं। लोडर स्मृति आवंटित करेगा, फिर इसकी प्रारंभिक सामग्री में प्रतिलिपि बनाएँ।

"बीएसएस": डेटा के समान, लेकिन शून्य के लिए शुरू किया गया।

"स्टैक": बस इसके प्रोग्राम स्टैक के लिए लोडर द्वारा आवंटित।

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

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

1

इस कोड:

void function() 
{ 
    static int var = 6; 

    // Make something with this variable 
    var++; 
} 

आंतरिक रूप से इस के समान है:

int only_the_compiler_knows_this_actual_name = 6; 

void function() 
{ 
    // Make something with the variable 
    only_the_compiler_knows_this_actual_name++; 
} 

दूसरे शब्दों में, यह जिसका नाम की "वैश्विक" चर एक प्रकार है, तथापि, किसी भी बाधा नहीं बनता है अन्य वैश्विक चर।

1

static चर सीमित क्षेत्र के साथ वैश्विक चर हैं। @user3386109

  1. static/वैश्विक चर कार्यक्रम के जीवनकाल के लिए मौजूद हैं।
  2. static/वैश्विक या तो करने के लिए कार्यक्रम शुरू हुआ पर प्रारंभ कर रहे हैं:

    ए यदि स्पष्ट रूप से प्रारंभ नहीं: बिट पैटर्न 0 करने के लिए।
    बी तो एक समारोह के बाहर परिभाषित अन्यथा करने के लिए की तरह double x = 1.23;

  3. static चर गुंजाइश एक स्पष्ट मूल्य के लिए या तो

    तक ही सीमित

    ए है: फ़ाइल गुंजाइश, फ़ाइल के भीतर ही कोड "देख" सकता चर ।
    बी। यदि किसी फ़ंक्शन के अंदर परिभाषित किया गया है: ब्लॉक स्कोप: केवल ब्लॉक के भीतर कोड चर को "देख" सकता है।

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

नोट: एकाधिक धागे के साथ, अन्य विचार लागू होते हैं - दिखाया नहीं गया।

static int fred = 11; 
int sally = 21; 

void foo2(void) { 
    static int fred = 31; 
    int sally = 41; 
    printf("static %d non-static %d\n", fred++, sally++); 
    { 
    printf("static %d non-static %d\n", fred++, sally++); 
    { 
     static int fred = 51; 
     int sally = 61; 
     printf("static %d non-static %d\n", fred++, sally++); 
    } 
    } 
} 

int main(void) { 
    printf("static %d non-static %d\n", fred++, sally++); 
    foo2(); 
    printf("static %d non-static %d\n", fred++, sally++); 
    foo2(); 
    return 0; 
} 

आउटपुट

static 11 non-static 21 
static 31 non-static 41 
static 32 non-static 42 
static 51 non-static 61 
static 12 non-static 22 
static 33 non-static 41 
static 34 non-static 42 
static 52 non-static 61 
संबंधित मुद्दे