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

الوصول إلى أعضاء الأب

جزء من قسم البرمجة كائنية التوجه في رحلة C على Coddy. الدرس 30 من 61.

الآن بعد أن فهمنا تضمين البنية وقاعدة العضو first، لنركّز على الجانب العملي: كيفية قراءة بيانات parent المضمّن وتعديلها من داخل دالة.

عندما تستقبل دالة بنية Child (أو مؤشرًا إليها)، يتطلب الوصول إلى أعضاء الوالد التنقل عبر البنية المضمّنة. تعتمد الصياغة على ما إذا كنت تتعامل مع قيمة أم مؤشر.

typedef struct {
    int id;
    int score;
} Parent;

typedef struct {
    Parent parent;
    char grade;
} Child;

باستخدام مؤشرًا إلى Child، استخدم معامل arrow للوصول إلى parent، ثم dot للوصول إلى أعضائه:

void update_score(Child* c, int new_score) {
    c->parent.score = new_score;  // سهم ثم نقطة
}

void print_info(Child* c) {
    printf("ID: %d, Score: %d\n", c->parent.id, c->parent.score);
}

باستخدام قيمة (مُمرَّرة بالنسخ)، استخدم النقاط في كل المواضع:

void show_id(Child c) {
    printf("ID: %d\n", c.parent.id);  // نقطة ثم نقطة
}

نمط الوصول المتسلسل هذا، child->parent.member أو child.parent.member، هو الطريقة التي تتفاعل بها مع البيانات الموروثة في نموذج التركيب في لغة C. وهو أكثر إسهابًا قليلًا من الوراثة الحقيقية، لكنه واضح وصريح بشأن العلاقة بين الأنواع.

challenge icon

التحدي

سهل

لنَبْنِ نظامًا لتقييم الطلاب يوضّح كيفية الوصول إلى البيانات وتعديلها داخل بنية embedded. ستنشئ تسلسلاً هرميًا يحتوي فيه Student على Person مضمّنة، ثم تكتب functions تعمل مع بيانات parent من خلال child.

ستنظّم code الخاص بك عبر ثلاثة ملفات:

  • student.h: Define تسلسل البنى الخاص بك مع include guards. Create بنية Person تحتوي على name (مصفوفة من character تتكوّن من 50 character) وage (عدد integer). ثم Define بنية Student التي تضمّن Person بوصفها أول member لها، وتضيف الحقل grade (عدد integer يمثّل درجته). Declare اثنتين من functions: set_person_age التي تستقبل Student* وقيمة age جديدة، وprint_student التي تستقبل Student* وتعرض all information.
  • student.c: Implement كلتا functions. يجب أن تعدّل function set_person_age الخاصة بك age داخل بنية Person المضمّنة. هنا ستتدرّب على صياغة arrow-then-dot (s->person.age). يجب أن تصل function print_student الخاصة بك إلى all fields من person المضمّن ومن student نفسه، وأن تعرضها.
  • main.c: Create متغيرًا من نوع Student وInitialize all حقوله. ثم استخدم set_person_age لتحديث age الخاص بـ person المضمّن، واستدعِ print_student لعرض النتيجة.

ستتلقى أربعة inputs: name الخاص بـ student (سلسلة نصية)، وinitial age الخاص به (عدد integer)، وgrade (عدد integer)، وnew age (عدد integer لتحديثه عبر function الخاصة بك).

في main file، Create student باستخدام القيم الأولية، ثم استدعِ set_person_age لتغيير age إلى القيمة الجديدة، وأخيرًا استدعِ print_student لعرض information المحدّثة.

يجب أن تبدو Output الخاصة بك كما يلي:

Name: Emma
Age: 21
Grade: 85

حيث إن Emma هو name، و21 هو age المحدّث (وليس initial age)، و85 هو grade. يتمثّل الدرس الأساسي هنا في التنقّل عبر البنية المضمّنة لقراءة وكتابة members الخاصة بـ parent.

جرّب بنفسك

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

int main() {
    char name[50];
    int initial_age, grade, new_age;
    
    // اقرأ المدخلات
    fgets(name, 50, stdin);
    name[strcspn(name, "\n")] = '\0';  // أزل سطر جديد
    scanf("%d", &initial_age);
    scanf("%d", &grade);
    scanf("%d", &new_age);
    
    // TODO: أنشئ متغير Student
    
    // TODO: هيّئ جميع حقول الـ student
    // - انسخ name إلى اسم الشخص المضمّن باستخدام strcpy
    // - عيّن عمر الشخص المضمّن إلى initial_age
    // - عيّن grade الخاص بـ student
    
    // TODO: استدعِ set_person_age لتحديث العمر إلى new_age
    
    // TODO: استدعِ print_student لعرض النتيجة
    
    return 0;
}
quiz iconاختبر نفسك

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

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم C عبر الإنترنت