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

تضمين الـ Struct

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

في اللغات كائنية التوجه مثل C++ أو Java، يتيح التوريث للفئة اكتساب الخصائص من فئة أب. لا تمتلك لغة C ميزة توريث مدمجة، ولكن يمكننا محاكاتها باستخدام تقنية تسمى composition — وهي وضع struct داخل آخر.

الفكرة بسيطة: إذا كان Child يحتاج إلى جميع خصائص Parent، فنحن نقوم بتضمين هيكل Parent كعضو في Child.

typedef struct {
    int id;
    char name[50];
} Parent;

typedef struct {
    Parent parent;  // بنية مضمنة
    int grade;
} Child;

هنا، يحتوي Child على كل ما يملكه Parent، بالإضافة إلى حقل grade الخاص به. هذا هو التركيب (composition) — فالابن "لديه" (has a) أب بدلاً من أن "يكون" (is a) أبًا، ولكن التأثير مشابه للوراثة.

للوصول إلى أعضاء الأب من خلال مثيل الابن، يمكنك استخدام عامل النقطة مرتين:

Child c;
c.parent.id = 101;
c.parent.name[0] = 'A';
c.grade = 5;

يشكل هذا النمط الأساس لبناء التسلسلات الهرمية للأنواع في لغة C. من خلال تضمين struct أساسي كـ عضو أول، نفتح المجال لتقنيات قوية سنستكشفها في الدروس القادمة.

challenge icon

التحدي

سهل

لنقم ببناء نظام بسيط لإدارة الموظفين يوضح تضمين الهياكل (struct embedding) - وهو أساس الوراثة في لغة C.

ستقوم بإنشاء تسلسل هرمي حيث يحتوي Employee على Person. هذا يحاكي كيفية عمل الوراثة: الموظف "هو" شخص لديه معلومات إضافية متعلقة بالوظيفة. من خلال تضمين هيكل Person داخل Employee، ستحصل على جميع خصائص الشخص بالإضافة إلى الحقول الخاصة بالموظف.

ستقوم بتنظيم الكود الخاص بك عبر ثلاثة ملفات:

  • types.h: قم بتعريف كلا الهيكلين هنا مع استخدام حراس التضمين (include guards). أولاً، أنشئ هيكل Person بحقلين: name (مصفوفة أحرف مكونة من 50 حرفاً) و age (عدد صحيح). ثم قم بتعريف هيكل Employee الذي يضمن Person كعضو أول له ويضيف حقل employee_id (عدد صحيح).
  • types.c: قم بتنفيذ دالة تسمى print_employee تأخذ مؤشراً إلى Employee وتطبع معلوماته. قم بالوصول إلى بيانات الشخص المضمنة باستخدام صيغة النقطة/السهم المتسلسلة التي تعلمتها.
  • main.c: قم بإنشاء متغير من نوع Employee، واملأ جميع حقوله (بما في ذلك اسم وعمر الشخص المضمن)، واستخدم دالة الطباعة الخاصة بك لعرض المعلومات.

ستتلقى ثلاثة مدخلات: name الموظف (سلسلة نصية)، و age الخاص به (عدد صحيح)، و employee ID الخاص به (عدد صحيح).

يجب أن تقوم دالة print_employee بإخراج معلومات الموظف بهذا التنسيق:

Employee: Alice
Age: 28
ID: 1001

حيث Alice هو الاسم، و 28 هو العمر، و 1001 هو معرف الموظف من مدخلاتك.

تذكر الوصول إلى أعضاء الهيكل المضمن من خلال العضو الأب - على سبيل المثال، للوصول إلى الاسم، ستنتقل عبر عضو person أولاً.

ورقة مرجعية

لا تمتلك لغة C وراثة مدمجة، ولكن يمكنك محاكاتها باستخدام التركيب (composition) — وهو تضمين هيكل (struct) داخل آخر.

لإنشاء علاقة أب-ابن، قم بتضمين هيكل الأب كعضو داخل هيكل الابن:

typedef struct {
    int id;
    char name[50];
} Parent;

typedef struct {
    Parent parent;  // Embedded struct
    int grade;
} Child;

يحتوي هيكل الابن على جميع خصائص الأب، بالإضافة إلى حقوله الإضافية الخاصة. يمثل هذا علاقة "يحتوي على" (has a).

للوصول إلى أعضاء الهيكل المضمن، استخدم عامل النقطة (dot operator) مرتين:

Child c;
c.parent.id = 101;
c.parent.name[0] = 'A';
c.grade = 5;

عند التعامل مع المؤشرات، استخدم عامل السهم (arrow operator) للوصول إلى أعضاء الهيكل المضمن:

Child *ptr = &c;
ptr->parent.id = 101;
ptr->grade = 5;

يعد تضمين الهيكل الأساسي كـ عضو أول نمطاً شائعاً يتيح تقنيات متقدمة لبناء تسلسلات هرمية للأنواع في لغة C.

جرّب بنفسك

#include <stdio.h>
#include <string.h>
#include "types.h"

int main() {
    // قراءة المدخلات
    char name[50];
    int age;
    int employee_id;
    
    fgets(name, 50, stdin);
    name[strcspn(name, "\n")] = '\0';  // إزالة سطر جديد
    scanf("%d", &age);
    scanf("%d", &employee_id);
    
    // TODO: إنشاء متغير Employee
    
    // TODO: ملء اسم وعمر الشخص المضمن
    // Hint: استخدم strcpy للاسم، وقم بالوصول إليه باستخدام employee.person.name
    
    // TODO: تعيين employee_id
    
    // TODO: استدعاء print_employee مع مؤشر إلى employee الخاص بك
    
    return 0;
}
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming