نطاق المتغيرات في C: شرح واضح للمتغيرات المحلية والعالمية

دقائق القراءة: 6

مقدمة إلى نطاق المتغيرات في C

عند كتابة البرامج بلغة C، ستتعامل كثيراً مع مفهوم Variable Scope أو نطاق المتغير. هذا المفهوم يحدد المكان الذي يمكن فيه الوصول إلى المتغير وقراءته أو تعديله داخل البرنامج. فهم هذا الموضوع ضروري لتجنّب الأخطاء المنطقية وأخطاء الترجمة، كما يساعدك على كتابة كود أكثر تنظيماً ووضوحاً.

في هذا المقال، سنتناول معنى نطاق المتغيرات في لغة C، ثم نوضح الفرق بين Local Variables وGlobal Variables باستخدام أمثلة عملية سهلة الفهم.

رسم توضيحي يشرح نطاق المتغيرات المحلية والعالمية في لغة C

ما المقصود بنطاق المتغير في C؟

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

ورغم أن البعض يربط النطاق بعمر المتغير داخل البرنامج، فإن المعنى العملي الأهم هو: أي أجزاء من الكود يمكنها الوصول إلى هذا المتغير؟

  • إذا كان المتغير متاحاً فقط داخل كتلة معينة، فهو Local.
  • إذا كان متاحاً من أكثر من دالة أو من كامل البرنامج وفقاً لموضع التصريح عنه، فهو Global.

المتغيرات المحلية في C داخل الكتل المتداخلة

في لغة C، يتم تحديد الكتل البرمجية باستخدام الأقواس المعقوفة { }. وكل كتلة قد تمتلك نطاقها المحلي الخاص. وهذا يعني أن المتغير الذي يتم تعريفه داخل كتلة معيّنة يكون غالباً متاحاً فقط داخلها.

مثال: الكتلة الداخلية يمكنها الوصول إلى متغير الكتلة الخارجية

# include <stdio.h>
int main () {
    int my_num = 7 ;
    {
        //add 10 my_num
        my_num = my_num + 10 ;
        //or my_num +=10 - more succinctly
        printf ( "my_num is %d" ,my_num);
    }
    return 0 ;
}

في هذا المثال، تم تعريف المتغير my_num داخل الكتلة الخارجية التابعة للدالة main()، ثم جرى استخدامه داخل كتلة داخلية متداخلة. بما أن الكتلة الداخلية تقع ضمن نطاق الكتلة الخارجية، فيمكنها الوصول إلى المتغير وتعديل قيمته.

الناتج سيكون كالتالي:

//Output
my_num is 17

هذا يوضح أن:

  • المتغير my_num متاح داخل الكتلة التي تم تعريفه فيها.
  • الكتل الداخلية المتداخلة يمكنها الوصول إلى متغيرات الكتل الخارجية.
  • يمكن تعديل القيمة داخل الكتلة الداخلية ما دام المتغير ضمن النطاق المسموح.

مثال: لا يمكن للكتلة الخارجية الوصول إلى متغير الكتلة الداخلية

# include <stdio.h>
int main () {
    int my_num = 7 ;
    {
        int new_num = 10 ;
    }
    printf ( "new_num is %d" ,new_num); //this is line 9
    return 0 ;
}

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

وعند الترجمة، سيظهر خطأ مشابه لما يلي:

Line Message
9 error: 'new_num' undeclared (first use in this function )

السبب واضح: المتغير new_num محلي بالنسبة للكتلة الداخلية، ولا يمكن استخدامه في الكتلة الخارجية.

قاعدة عامة لفهم النطاق المحلي داخل الكتل

{
    /*OUTER BLOCK*/

    {
        //contents of the outer block just before the start of this block
        //CAN be accessed here

        /*INNER BLOCK*/
    }

    //contents of the inner block are NOT accessible here
}

القاعدة هنا بسيطة:

  1. الكتلة الداخلية ترى ما هو مُعرّف قبلها في الكتلة الخارجية.
  2. الكتلة الخارجية لا ترى المتغيرات التي تم تعريفها داخل الكتلة الداخلية بعد انتهائها.

نطاق المتغيرات المحلية في كتل ودوال مختلفة

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

مثال: متغير محلي داخل main() لا يمكن الوصول إليه من دالة أخرى

# include <stdio.h>
int main () {
    int my_num = 7 ;
    printf ( "%d" ,my_num);
    my_func();
    return 0 ;
}

void my_func () {
    printf ( "%d" ,my_num);
}

في هذا المثال، تم تعريف المتغير my_num داخل الدالة main(). وبالرغم من أن الدالة my_func() يتم استدعاؤها من داخل main()، فإن ذلك لا يمنحها حق الوصول إلى المتغير my_num.

وعند الترجمة، سيظهر خطأ مشابه لما يلي:

Line Message
13 error: 'my_num' undeclared (first use in this function )

هذا يعني أن المتغير my_num محلي داخل main() فقط، ولا يمكن استخدامه داخل my_func() لأنه ليس ضمن نطاقها.

صياغة عامة لفهم النطاق المحلي بين الكتل المختلفة

{
    /*BLOCK 1*/
    // contents of BLOCK 2 cannot be accessed here
}

{
    /*BLOCK 2*/
    // contents of BLOCK 1 cannot be accessed here
}

إذا تم تعريف متغير داخل كتلة أو دالة معينة، فلا يمكن الوصول إليه من كتلة أو دالة أخرى إلا إذا كان ضمن نطاق مشترك أو تم تمريره بطريقة مناسبة مثل Function Parameters.

المتغيرات العالمية في C

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

مثال: متغير عالمي يمكن الوصول إليه من أكثر من دالة

# include <stdio.h>
int my_num = 7 ;

int main () {
    printf ( "my_num can be accessed from main() and its value is %d\n" ,my_num);
    //call my_func
    my_func();
    return 0 ;
}

void my_func () {
    printf ( "my_num can be accessed from my_func() as well and its value is %d\n" ,my_num);
}

في هذا المثال، تم تعريف my_num خارج الدالتين main() وmy_func()، لذلك أصبح متغيراً عالمياً. يمكن لكلتا الدالتين الوصول إليه وقراءة قيمته مباشرة.

الناتج سيكون كالتالي:

//Output
my_num can be accessed from main() and its value is 7
my_num can be accessed from my_func() as well and its value is 7

وهذا يثبت أن المتغيرات العالمية:

  • لا تكون محصورة داخل دالة واحدة.
  • يمكن مشاركتها بين أكثر من دالة داخل البرنامج.
  • تُستخدم عندما تحتاج عدة أجزاء من البرنامج إلى نفس البيانات.

قاعدة عامة لفهم النطاق العالمي

//all global variables are declared here

function1() {
    // all global variables can be accessed inside function1
}

function2() {
    // all global variables can be accessed inside function2
}

الفرق بين Local Variables و Global Variables في C

العنصر Local Variable Global Variable
مكان التعريف داخل دالة أو كتلة خارج جميع الدوال
نطاق الوصول محدود داخل نفس الكتلة أو الدالة متاح لعدة دوال داخل الملف
الأمان والتنظيم أفضل في تقليل التداخل قد يزيد الترابط بين أجزاء البرنامج
إمكانية التعديل ضمن النطاق المحلي فقط يمكن تعديله من أي دالة تصل إليه
الاستخدام الأمثل للقيم المؤقتة والخاصة بكل دالة للقيم المشتركة بين أجزاء متعددة

متى تستخدم المتغير المحلي ومتى تستخدم المتغير العالمي؟

الاختيار بين النوعين لا يعتمد فقط على إمكانية الوصول، بل أيضاً على جودة تصميم البرنامج.

يفضّل استخدام Local Variables عندما:

  • تكون القيمة مطلوبة داخل دالة واحدة فقط.
  • ترغب في تقليل الاعتماد المتبادل بين أجزاء البرنامج.
  • تسعى إلى كتابة كود أسهل في الاختبار والصيانة.

يمكن استخدام Global Variables عندما:

  • تحتاج عدة دوال إلى نفس البيانات بشكل مستمر.
  • تكون هناك حالة مشتركة عامة داخل البرنامج.
  • يكون الاستخدام محدوداً ومنظماً لتفادي التعقيد.

ومع ذلك، في المشاريع الكبيرة، يُنصح بعدم الإفراط في استخدام Global Variables لأن ذلك قد يجعل تتبع تغيّر القيم أكثر صعوبة، ويزيد من احتمالات الأخطاء.

أفضل الممارسات لفهم نطاق المتغيرات في C

  • عرّف المتغير في أضيق نطاق ممكن.
  • استخدم المتغيرات المحلية كلما كان ذلك كافياً.
  • تجنب إنشاء متغيرات عالمية إلا عند وجود مبرر واضح.
  • اختر أسماء متغيرات تعبّر عن وظيفتها لتسهيل قراءة الكود.
  • إذا احتاجت دالة إلى قيمة من دالة أخرى، ففكر في تمريرها كوسيط بدلاً من الاعتماد على متغير عالمي.

الخلاصة التقنية

فهم Variable Scope in C خطوة أساسية لأي مبرمج يريد كتابة كود صحيح ومنظم. المتغير المحلي يمنحك عزلاً أفضل وتحكماً أدق داخل الدوال والكتل، بينما يوفر المتغير العالمي سهولة مشاركة البيانات بين الدوال، لكن على حساب التنظيم إذا أُسيء استخدامه. من الناحية التقنية، الأفضل دائماً هو تقليل النطاق قدر الإمكان، لأن ذلك يجعل البرنامج أكثر أماناً وأسهل في الصيانة والتطوير.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *