Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

حواجز التضمين

جزء من قسم Object Oriented Programming في رحلة C على Coddy — الدرس 2 من 61.

عندما يتم تضمين ملف رأس (header file) عدة مرات في مشروع ما، يرى المترجم (compiler) نفس التصريحات بشكل متكرر، مما يتسبب في حدوث أخطاء. يحدث هذا عادةً عندما تقوم ملفات متعددة بتضمين نفس ملف الرأس، أو عندما تقوم ملفات الرأس بتضمين بعضها البعض. تحل حواجز التضمين (Include guards) هذه المشكلة.

يستخدم حارس التضمين (include guard) ثلاثة من توجيهات المعالج المسبق لضمان معالجة محتويات الملف الرأسي (header) مرة واحدة فقط:

// math_utils.h
#ifndef MATH_UTILS_H
#define MATH_UTILS_H

int add(int a, int b);

#endif

إليك كيفية عمل ذلك: يتحقق #ifndef MATH_UTILS_H مما إذا كان الرمز MATH_UTILS_H لم يتم تعريفه بعد. إذا لم يكن قد تم تعريفه، يستمر المعالج المسبق (preprocessor) ويقوم بتعريفه فوراً باستخدام #define MATH_UTILS_H. يتم تضمين كل شيء بين هذه النقطة و #endif في عملية التجميع (compilation).

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

كل ملف رأس (header file) تقوم بإنشائه يجب أن يحتوي على حواجز تضمين (include guards). هذه ممارسة قياسية تمنع أخطاء التجميع (compilation errors) وتجعل الكود الخاص بك آمناً للتضمين من أي مكان في مشروعك.

challenge icon

التحدي

سهل

لنقم بحماية ملف ترويسة (header file) من التضمين المزدوج عن طريق إضافة حراس التضمين (include guards). ستبني على أداة التحية من الدرس السابق، ولكن هذه المرة تأكد من أن الترويسة آمنة للتضمين عدة مرات.

ستقوم بإنشاء ملفين:

  • greet.h: ملف الترويسة الخاص بك الذي يحتوي على إعلان الدالة لـ greet. هذه المرة، قم بتغليف المحتويات بالكامل بحراس التضمين باستخدام الرمز GREET_H.
  • main.c: ملفك الرئيسي الذي يتضمن الترويسة، وينفذ الدالة greet ويستدعيها من main().

يجب أن تقبل الدالة greet معاملًا من نوع const char* للاسم وتطبع:

Hello, Alice!

يجب أن يتبع ملف الترويسة الخاص بك هذا الهيكل:

#ifndef GREET_H
#define GREET_H

// إعلان الدالة هنا

#endif

ستتلقى مدخلاً واحداً: اسم (سلسلة نصية).

اطبع رسالة التحية تماماً كما هو موضح في التنسيق أعلاه، مع استبدال Alice بالاسم المقدم.

ورقة مرجعية

تمنع حواجز التضمين (Include guards) معالجة ملفات الرأس عدة مرات أثناء عملية التجميع، مما قد يتسبب في حدوث أخطاء.

يستخدم حاجز التضمين ثلاثة توجيهات للمعالج المسبق:

#ifndef HEADER_NAME_H
#define HEADER_NAME_H

// محتويات ملف الرأس هنا

#endif

يتحقق #ifndef مما إذا كان الرمز لم يتم تعريفه. إذا لم يكن معرفاً، يقوم #define بتعريفه وتتم معالجة المحتويات. في عمليات التضمين اللاحقة، يكون الرمز معرفاً بالفعل، لذا يتم تخطي الكتلة بالكامل.

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

يجب أن يحتوي كل ملف رأس على حواجز تضمين كممارسة قياسية.

جرّب بنفسك

#include <stdio.h>
#include "greet.h"

// TODO: قم بتنفيذ دالة greet التي تطبع "!Hello, <name>"

int main() {
    char name[100];
    scanf("%s", name);
    
    // TODO: قم باستدعاء دالة greet مع الاسم
    
    return 0;
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس Object Oriented Programming