مرئية الأسماء

في C++، الموضع الذي يتم فيه تعريف المتغير يؤثر على الأماكن التي يمكن استخدامه فيها.

النطاقات

النطاق هو الجزء من البرنامج الذي يمكن تعريف المتغير فيه والوصول إليه مباشرة باستخدام اسمه. إذا تم تعريف متغير في نطاق معين فإننا نقول أن الاسم مرئي في هذا النطاق. أغلب النطاقات هي المناطق المحاطة بالأقواس المعقوفة {}. المنطقة خارج أي نطاق تُسمى النطاق العام، وأي منطقة أخرى تُسمى نطاق محلي.

#include<iostream>
using namespace std;

// نطاق عام
int x = 5;

int main() {
    // نطاق محلي 1
    int y = 4
    
    for (int i = 0 ; i < 5 ; i++) {
        // نطاق محلي 2
        int z = 20;
        if (i % 2 == 0) {
            // نطاق محلي 4
            cout << z + x << ' ' << z + y << endl;
        }
        else {
            // نطاق محلي 4
            cout << z - y << ' ' << z - x << endl;
        }
    }
}

في هذا المثال لدينا نطاق عام و أربعة نطاقات محلية. لاحظ أن النطاق 1 يمتد خلال الدالة main() بأكملها، والنطاق 2 هو المنطقة داخل حلقة for، والنطاقان 3 و4 هما المنطقتان داخل كل من if و else.

أين يكون المتغير مرئيًا؟

المتغيرات المعرفة بشكل عام (وتُسمى أيضًا متغيرات عامة) تكون مرئية ويمكن استخدامها في جميع النطاقات بعد تعريفها. المتغيرات المعرفة محليًا (وتُسمى أيضًا متغيرات محلية) تكون مرئية فقط داخل النطاق الذي تم تعريفها فيه، ويشمل ذلك النطاقات الداخلية.

بالنظر إلى المثال السابق، هذه هي مرئية كل من x و y و i و z:

اسم المتغير النطاق المعرف فيه النطاقات القادرة على رؤية المتغير
x النطاق العام جميع النطاقات
y النطاق 1 (داخل ()main) جميع النطاقات المحلية
i حلقة for التي تبدأ النطاق 2 النطاقات 2 و3 و4
z النطاق 2 (داخل for) النطاقات 2 و3 و4

لاحظ أن المتغيرات التي تم تعريفها داخل حلقة for تنتمي إلى نطاق الحلقة نفسه، حتى لو كان التعريف قبل الأقواس المعقوفة.

Warning

استخدام متغير خارج نطاقه يؤدي إلى خطأ في الترجمة (compilation error).

التسمية داخل النطاق

في النطاق الواحد يمكن للاسم أن يمثل متغيرًا واحدًا فقط.

#include<iostream>
using namespace std;

int main() {
    int x = 5;
    string x = "Hello world"; // تم تعريفه مرتين في النطاق نفسه x لأن (compilation error) خطأ في الترجمة
}

على الرغم من أننا ذكرنا أن الاسم يمكن أن يمثل متغيرًا واحدًا فقط، إلا أنه يمكننا تعريف متغير في نطاق ثم تعريف متغير آخر بالاسم نفسه في نطاق داخلي. في هذه الحالة، عند استخدام هذا الاسم سيستخدم المتغير الداخلي.

#include<iostream>
using namespace std;

int x = 5;

int main() {
    int x;                        // لا مشكلة. لأننا في نطاق داخلي
    cin >> x;
    
    if (x == 5) {
        string x = "Hello world"; //  أيضا مسموح لأننا في نطاق داخلي أيضا
        cout << x << endl;
    }
    else {
        cout << x << endl;
    }
}