मैंने दायरे के बारे में पढ़ा है और सोचा है कि मैं इसे अब तक समझ गया हूं। मुझे किसी अन्य प्रोग्राम में समस्या थी और इसे ठीक करने का प्रयास करते समय मैंने पाया कि लूप के दायरे में वेरिएबल मेरी अपेक्षा से काफी असामान्य व्यवहार करते हैं। इसलिए मैंने यह कार्यक्रम यह दिखाने के लिए बनाया है कि मेरा क्या मतलब है:

#include <iostream>

using namespace std;

int main()
{
    int num = 6;
    for (int i = 0; i < 5; i++)
    {
        cout << num;
        int num = 5;
        cout << num;
    }
}

मुझे लूप के माध्यम से पहले रन की उम्मीद थी, पहला cout << num अपरिभाषित होगा क्योंकि यह एक नया दायरा है और num को अभी तक परिभाषित नहीं किया गया है। लेकिन इसके बजाय, यह सिर्फ पिछले दायरे से num के मान का उपयोग करता है। फिर जब लूप के अंदर num को 5 से इनिशियलाइज़ किया जाता है, उसके बाद, num के लिए सभी आउटपुट 5 होने चाहिए। लेकिन इसके बजाय आउटपुट 656565 था ...

तो इस जानकारी का उपयोग करके मैंने एक मॉडल बनाया जो मुझे लगता है कि चर के दायरे ने काम किया और ऐसा लगता है:

Scope Diagram

तो छवि में आप देख सकते हैं कि मुझे लगता है कि दायरा कैसे काम करता है और मुझे लगता है कि लूप के माध्यम से प्रत्येक पुनरावृत्ति के लिए, लूप को चर का एक नया दायरा मिलता है और फिर लूप के अंत में अपना दायरा हटा देता है और एक नया प्राप्त करता है अगले पुनरावृत्ति की शुरुआत जो बताती है कि क्यों लूप पिछले स्कोप से num का उपयोग करता है जब तक कि वर्तमान स्कोप में num को फिर से इनिशियलाइज़ नहीं किया जाता है। क्या मेरी समझ सही है?

3
user6544024 16 जून 2018, 15:24

3 जवाब

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

मुझे लूप के माध्यम से पहले रन की उम्मीद थी, पहला cout << num अपरिभाषित होगा क्योंकि यह एक नया दायरा है और num को अभी तक परिभाषित नहीं किया गया है। लेकिन इसके बजाय, यह सिर्फ पिछले दायरे से num के मान का उपयोग करता है। फिर जब लूप के अंदर num को 5 से इनिशियलाइज़ किया जाता है, उसके बाद, num के लिए सभी आउटपुट 5 होने चाहिए। लेकिन इसके बजाय आउटपुट 656565 था ...

यहां आपकी समझ गलत है, और जो आउटपुट आप देख रहे हैं वह सही है।

लूप के भीतर, पहला cout << num वेरिएबल num को प्रिंट करेगा जिसे लूप से पहले परिभाषित किया गया था। दूसरा लूप के अंदर परिभाषित वेरिएबल को प्रिंट करेगा।

लूप में int num = 5 पहले से परिभाषित चर (बाहरी दायरे में) को प्रभावित नहीं करता है। यह एक पूरी तरह से नए वैरिएबल को परिभाषित करता है, और इसे 5 में इनिशियलाइज़ करता है। लूप से पहले परिभाषित num के मान पर कोई प्रभाव नहीं पड़ता है। इसलिए बाहर परिभाषित num का मान 6 रहेगा, और अंदर परिभाषित (प्रत्येक लूप पुनरावृत्ति में बनाया गया) का मान 5 होगा। यद्यपि आपका कोड उन्हें एक ही नाम देता है (num) वे पूरी तरह से अलग चर हैं, और स्मृति में अलग-अलग पते पर कब्जा कर लेते हैं - इसलिए एक को बदलने से दूसरा नहीं बदलता है।

व्यावहारिक रूप से आपका कोड

int num = 6;
for (int i = 0; i < 5; i++)
{
    cout << num;
    int num = 5;
    cout << num;
}

कल्पित रूप से बराबर है

int num = 6;
for (int i = 0; i < 5; i++)
{
    cout << num;
    {                   //  note another scope introduced here
        int num = 5;
        cout << num;
    }
}

यह काल्पनिक तुल्यता एक मानक में आवश्यकताओं के परिणामस्वरूप होती है, यदि एक ब्लॉक में स्वचालित भंडारण अवधि के कई चर बनाए जाते हैं, तो वे निर्माण के अपने क्रम के विपरीत क्रम में मौजूद नहीं रहते हैं। (यानी यदि आप क्लास ऑब्जेक्ट्स के कंस्ट्रक्टर्स और डिस्ट्रक्टर्स की कॉल्स को ट्रैक करते हैं, तो स्वचालित स्टोरेज अवधि की सबसे हाल ही में निर्मित ऑब्जेक्ट को पहले नष्ट कर दिया जाएगा)।

cout स्टेटमेंट्स num के मान तक नहीं पहुंच सकते, जब तक कि यह मौजूदा दायरे में या एक युक्त दायरे में न हो। इसलिए, इसे इस तरह से देखने का अर्थ है कि पहले cout << num में केवल बाहरी num (6 से आरंभिक) की दृश्यता है, न कि आंतरिक। जबकि दूसरा cout << num आंतरिक दायरे में परिभाषित चर का उपयोग करता है।

1
Peter 16 जून 2018, 16:20

क्या मेरी समझ सही है?

हां लेकिन num नहीं पुन: प्रारंभ है। यह दूसरे वेरिएबल को परिभाषित करता है।
"आंतरिक" num छाया "बाहरी" num.

चूंकि num के पास ब्लॉक स्कोप है। rel="nofollow noreferrer">basic.scope.block:

एक ब्लॉक में घोषित नाम उस ब्लॉक के लिए स्थानीय है; इसमें ब्लॉक स्कोप है। इसका संभावित दायरा इसके घोषणा के बिंदु पर शुरू होता है और समाप्त पर होता है इसके ब्लॉक का अंत। ब्लॉक स्कोप पर घोषित एक वैरिएबल एक स्थानीय है चर।

int main() {
   int num = 6; // block scope (a) ---- point of declaration for (a) begins
   for (int i = 0; i < 5; i++)
   {
      cout << num; // uses (a)
      int num = 5; // block scope (b) ---- point of declaration for (b) begins
      cout << num; // uses (b)         ||
   }               //                 ---- (b) goes out of scope here
} // ---- (a) goes out of scope here
4
Joseph D. 16 जून 2018, 16:22

आपका आरेख सही है यदि स्कोप 1 सबसे बाहरी स्कोप है और स्कोप 4 सबसे आंतरिक स्कोप है। "अधिलेखित" शब्द का आपका उपयोग सी ++ के लिए सम्मेलन नहीं है। चर अधिलेखित नहीं हैं, बल्कि छाया हुआ हैं। समान छायांकन कई प्रोग्रामिंग भाषाओं का हिस्सा है।

2
snow_abstraction 16 जून 2018, 15:33