فئات التخزين في لغة C: تلقائي، خارجي، ثابت، سجل (أمثلة)

⚡ ملخص ذكي

تحدد فئات التخزين في لغة C نطاق كل متغير، وعمره الافتراضي، وقيمته الافتراضية، وموقعه في الذاكرة، باستخدام أربعة محددات - auto، وregister، وstatic، وextern - للتحكم في مكان وجود البيانات ومدة بقائها أثناء التنفيذ.

  • 🗂️ أربع فئات تخزين: توفر لغة C محددات auto و register و static و extern لوصف كل متغير.
  • 🏠 السيارات: الفئة المحلية الافتراضية، محصورة في كتلتها وتحتفظ بقيمة عشوائية حتى يتم تعيينها.
  • ⚡ تسجيل: يطلب تخزين سجلات وحدة المعالجة المركزية للوصول بشكل أسرع إلى المتغيرات المستخدمة بشكل متكرر مثل العدادات.
  • ♻️ ثابتة: يحافظ على قيمة متغيرة بين استدعاءات الدالة، وتكون قيمته الافتراضية صفرًا عند الاستخدام الأول.
  • 🌐 خارجي: مشاركة متغير أو دالة عامة عبر ملفات مصدر متعددة دون إعادة تعريفها.
  • 📊 النطاق والعمر الافتراضي: تحدد كل فئة مكان ظهور المتغير ومدة بقائه.

فئات التخزين في C.

ما هي فئة التخزين في C؟

تمثل فئة التخزين إمكانية رؤية متغير وموقعه. وهي تخبرنا من أي جزء من الكود يمكننا الوصول إلى متغير. تُستخدم فئة التخزين في لغة C لوصف الأشياء التالية:

  • النطاق المتغير.
  • الموقع الذي سيتم تخزين المتغير فيه.
  • القيمة المبدئية للمتغير.
  • عمر المتغير.
  • من يستطيع الوصول إلى المتغير؟

وبالتالي يتم استخدام فئة التخزين لتمثيل المعلومات حول المتغير.

ملاحظة: لا يرتبط المتغير فقط بـ نوع البياناتوقيمتها ولكن أيضًا فئة تخزين.

ما هي أنواع فئات التخزين في لغة C؟

هناك أربعة أنواع من فئات التخزين القياسية. يمثل الجدول أدناه فئات التخزين في C.

فئة التخزين الهدف
السيارات إنها فئة تخزين افتراضية.
خارجي إنه متغير عالمي.
ساكن إنه متغير محلي قادر على إرجاع قيمة حتى عند نقل التحكم إلى استدعاء الوظيفة.
تسجيل جديد وهو متغير يتم تخزينه داخل السجل.

فئة التخزين التلقائي في C

تسمى المتغيرات المحددة باستخدام فئة التخزين التلقائي بالمتغيرات المحلية. يشير Auto إلى فئة التخزين التلقائي. يوجد المتغير في فئة التخزين التلقائي بشكل افتراضي إذا لم يتم تحديده بشكل صريح.

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

يتم استخدام الكلمة الأساسية auto لتحديد فئة التخزين التلقائي. بشكل افتراضي، يحتوي المتغير التلقائي على قيمة غير صحيحة.

Example, auto int age;

يعرّف البرنامج أدناه دالة تحتوي على متغيرين محليين

int add(void) {
   int a=13;
   auto int b=48;
return a+b;}

نأخذ برنامجًا آخر يوضح مستوى النطاق "مستوى الرؤية" للمتغيرات التلقائية في كل رمز كتلة والتي تكون مستقلة عن بعضها البعض:

#include <stdio.h>
int main( )
{
  auto int j = 1;
  {
    auto int j= 2;
    {
      auto int j = 3;
      printf ( " %d ", j);
    }
    printf ( "\t %d ",j);
  }
  printf( "%d\n", j);}

الإخراج:

 3 2 1

فئة التخزين الخارجية في C

يشير Extern إلى فئة التخزين الخارجية. يتم استخدام فئة التخزين الخارجية عندما يكون لدينا وظائف أو متغيرات عامة مشتركة بين ملفين أو أكثر.

تُستخدم الكلمة المفتاحية extern لتعريف متغير أو دالة عامة في ملف آخر لتوفير مرجع للمتغير أو الدالة التي تم تعريفها بالفعل في الملف الأصلي.

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

Example, extern void display();

الملف الأول: main.c

#include <stdio.h>
extern i;
main() {
   printf("value of the external integer is = %d\n", i);
   return 0;}

الملف الثاني: original.c

#include <stdio.h>
i=48;

النتيجة:

 value of the external integer is = 48

لتجميع وتشغيل التعليمات البرمجية أعلاه، اتبع الخطوات التالية

الخطوة 1) إنشاء مشروع جديد،

  • حدد تطبيق وحدة التحكم
  • انقر فوق انتقال

إنشاء مشروع جديد في Code Blocks

الخطوة 2) حدد C وانقر فوق التالي

اختر لغة C

الخطوة 3) انقر فوق التالي

انقر فوق التالي

الخطوة الرابعة) أدخل التفاصيل وانقر على التالي

أدخل تفاصيل المشروع

الخطوة 5) انقر فوق إنهاء

انقر فوق "إنهاء"

الخطوة 6) ضع الكود الرئيسي كما هو موضح في البرنامج السابق في ملف main.c واحفظه

أضف الكود إلى ملف main.c

الخطوة 7) قم بإنشاء ملف C جديد [ملف -> جديد -> ملف فارغ، احفظه (باسم original.c) وأضفه إلى المشروع الحالي بالنقر فوق "موافق" في مربع الحوار.

أنشئ ملف original.c

الخطوة 8) ضع واحفظ كود C الخاص بملف original.c الموضح في المثال السابق بدون الدالة main().

أضف الكود إلى الملف original.c

الخطوة 9) قم ببناء مشروعك وتشغيله. تظهر النتيجة في الشكل التالي

إخراج البرنامج

فئة التخزين الثابتة في C

يتم استخدام المتغيرات الثابتة داخل الوظيفة/الملف كمتغيرات ثابتة محلية. يمكن استخدامها أيضًا ك المتغير العالمي

  • المتغير المحلي الثابت هو متغير محلي يحتفظ بقيمته ويخزنها بين استدعاءات الوظائف أو الكتلة ويظل مرئيًا فقط للوظيفة أو الكتلة التي تم تعريفها فيها.
  • المتغيرات العامة الثابتة هي متغيرات عامة لا تظهر إلا في الملف الذي تم تعريفها فيه.
Example: static int count = 10;

ضع في اعتبارك أن المتغير الثابت له قيمة أولية افتراضية صفر ويتم تهيئته مرة واحدة فقط خلال عمره.

#include <stdio.h> /* function declaration */
void next(void);
static int counter = 7; /* global variable */
main() {
 while(counter<10) {
      next();
      counter++;   }
return 0;}
void next( void ) {    /* function definition */
   static int iteration = 13; /* local static variable */
   iteration ++;
   printf("iteration=%d and counter= %d\n", iteration, counter);}

النتيجة:

iteration=14 and counter= 7
iteration=15 and counter= 8
iteration=16 and counter= 9

يمكن الوصول إلى المتغيرات العامة في جميع أنحاء الملف بينما لا يمكن الوصول إلى المتغيرات الثابتة إلا لجزء معين من التعليمات البرمجية.

عمر المتغير الثابت موجود في كود البرنامج بأكمله. المتغير الذي يتم الإعلان عنه أو تهيئته باستخدام كلمة أساسية ثابتة يحتوي دائمًا على صفر كقيمة افتراضية.

تسجيل فئة التخزين في C

يمكنك استخدام فئة تخزين السجل عندما تريد تخزين المتغيرات المحلية داخل الوظائف أو الكتل في سجلات وحدة المعالجة المركزية بدلاً من ذلك رامات للوصول السريع إلى هذه المتغيرات. على سبيل المثال، تعد "العدادات" مرشحًا جيدًا لتخزينها في السجل.

Example: register int age;

تُستخدم الكلمة المفتاحية register لتعريف فئة تخزين السجلات. وتستمر المتغيرات المُعرَّفة باستخدام فئة تخزين السجلات طوال فترة البرنامج.

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

المتغيرات المعلنة باستخدام فئة تخزين التسجيل ليس لها قيمة افتراضية. غالبًا ما يتم الإعلان عن هذه المتغيرات في بداية البرنامج.

#include <stdio.h> /* function declaration */
main() {
{register int  weight;
int *ptr=&weight ;/*it produces an error when the compilation occurs ,we cannot get a memory location when dealing with CPU register*/}
}

الإخراج:

error: address of register variable 'weight' requested

يوضح الجدول التالي ملخصًا للميزات الرئيسية لكل فئة تخزين تُستخدم عادةً في برمجة C

فئة التخزين إعلان التخزين القيمة الأولية الافتراضية مجال حياة
السيارات داخل وظيفة/كتلة ذاكرة لا يمكن التنبؤ به داخل الوظيفة/الكتلة داخل الوظيفة/الكتلة
تسجيل جديد داخل وظيفة/كتلة سجلات وحدة المعالجة المركزية قمامة داخل الوظيفة/الكتلة داخل الوظيفة/الكتلة
خارجي خارج جميع الوظائف ذاكرة ببساطة وبدون الحاجة لخبرة ومعرفة الملف بأكمله والملفات الأخرى حيث تم تعريف المتغير على أنه خارجي وقت تشغيل البرنامج
ثابت (محلي) داخل وظيفة/كتلة ذاكرة ببساطة وبدون الحاجة لخبرة ومعرفة داخل الوظيفة/الكتلة وقت تشغيل البرنامج
ثابت (عالمي) خارج جميع الوظائف ذاكرة ببساطة وبدون الحاجة لخبرة ومعرفة تجوال حول العالم وقت تشغيل البرنامج

الأسئلة الشائعة

يُحدد نطاق المتغير مكان ظهوره في الكود، بينما يُحدد عمره مدة بقائه في الذاكرة. قد يكون للمتغير نطاق كتلة واحدة، ومع ذلك قد يمتد عمره طوال مدة البرنامج.

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

لا، كلمة "register" مجرد طلب؛ قد يتجاهلها المترجم إذا لم يكن هناك سجل متاح. تعمل المترجمات الحديثة على تحسين استخدام السجلات تلقائيًا، لذا نادرًا ما تُستخدم هذه الكلمة الآن.

تُخزَّن المتغيرات الثابتة والخارجية في جزء من الذاكرة مُهيأ بقيمة صفرية طوال مدة البرنامج، لذا تبدأ قيمتها من الصفر. أما المتغيرات التلقائية، فتُعيد استخدام ذاكرة المكدس، وتحتفظ بـping أي قيمة متبقية.

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

في الغالب، ولكن ليس تماماً. C++ تم إهمال الكلمة المفتاحية register واستُبدلت الكلمة المفتاحية auto لاستنتاج النوع. تتصرف الكلمتان static و extern بشكل مشابه، على الرغم من ذلك. C++ يضيف قواعد تخزين thread_local و class-member.

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

مساعد الطيار جيثب يقوم بإكمال العدادات الثابتة، والتصريحات الخارجية عبر الملفات، وتلميحات التسجيل تلقائيًا، ثم يشرح النطاق وفترة الحياة بشكل مضمن أثناء الكتابة.

تلخيص هذه التدوينة بـ: