تمرير الهياكل بالقيمة
جزء من قسم Logic & Flow في رحلة C على Coddy — الدرس 46 من 63.
الآن بعد أن عرفت كيفية التعامل مع الـ structs والمؤشرات إلى الـ structs، حان الوقت لتعلم كيفية تمرير الـ structs بالكامل إلى الدوال. عندما تمرر struct إلى دالة كمعامل (parameter)، تستخدم لغة C أسلوب pass-by-value، مما يعني أن الدالة تتلقى نسخة كاملة من الـ struct.
إليك الصيغة البرمجية لدالة تقبل معاملًا من نوع struct:
void functionName(struct StructureName parameterName) {
// متن الدالة
}باستخدام هيكل Point المألوف لدينا كمثال:
void printPoint(struct Point p) {
printf("Point coordinates: (%d, %d)\n", p.x, p.y);
}المفهوم الأساسي الذي يجب فهمه هو أن أي تغييرات تجريها على الـ struct داخل الدالة لن تؤثر على الـ struct الأصلي في الدالة المستدعية. وذلك لأن الدالة تعمل مع نسختها الخاصة من البيانات.
هذا النهج مفيد عندما تريد قراءة بيانات الـ struct أو عرضها دون المخاطرة بإجراء تعديلات عرضية على الأصل. ومع ذلك، ضع في اعتبارك أن نسخ الـ structs الكبيرة قد يكون غير فعال من حيث الذاكرة والأداء.
التحدي
سهلقم بإنشاء برنامج بلغة C يوضح كيفية تمرير الهياكل (structs) إلى الدوال بالقيمة (by value). يجب أن يقوم برنامجك بما يلي:
- تعريف
structباسمRectangleبالأعضاء التالية:- عدد صحيح
widthلتخزين عرض المستطيل - عدد صحيح
heightلتخزين ارتفاع المستطيل - مصفوفة أحرف
colorبحجم 15 لتخزين لون المستطيل
- عدد صحيح
- كتابة دالة باسم
displayRectangleتقوم بما يلي:- تستقبل
Rectanglestruct كمعامل (تمرير بالقيمة - pass-by-value) - تطبع معلومات المستطيل بهذا التنسيق الدقيق:
Rectangle Details:Width: [width]Height: [height]Color: [color]Area: [area]
- تحسب وتطبع المساحة (width × height)
- تستقبل
- كتابة دالة باسم
modifyRectangleتقوم بما يلي:- تستقبل
Rectanglestruct كمعامل (تمرير بالقيمة - pass-by-value) - تضاعف كلاً من عرض وارتفاع المستطيل
- تغير اللون إلى "Modified"
- تطبع
Inside modifyRectangle function: - تستدعي
displayRectangleلعرض المستطيل المعدل
- تستقبل
- في الدالة الرئيسية (main function):
- إنشاء متغير من نوع
Rectangleباسمrect - قراءة العرض، الارتفاع، واللون من المدخلات وتعيينها لأعضاء الـ struct
- طباعة
Original rectangle: - استدعاء
displayRectangleلعرض المستطيل الأصلي - استدعاء
modifyRectangleمع المستطيل - طباعة
After modifyRectangle call: - استدعاء
displayRectangleمرة أخرى لإظهار أن المستطيل الأصلي لم يتغير
- إنشاء متغير من نوع
يوضح هذا التحدي المفهوم الأساسي للتمرير بالقيمة (pass-by-value) مع الهياكل (structs): عندما تمرر struct إلى دالة، تستقبل الدالة نسخة كاملة من الـ struct. أي تعديلات يتم إجراؤها داخل الدالة تؤثر فقط على النسخة، وليس على الـ struct الأصلي في الدالة المستدعية.
ورقة مرجعية
عند تمرير الهياكل (structs) إلى الدوال، تستخدم لغة C **التمرير بالقيمة** (pass-by-value)، مما يعني أن الدالة تستقبل نسخة كاملة من الهيكل.
صيغة الدالة لقبول معامل من نوع هيكل (struct):
void functionName(struct StructureName parameterName) {
// جسم الدالة
}مثال مع هيكل Point:
void printPoint(struct Point p) {
printf("Point coordinates: (%d, %d)\n", p.x, p.y);
}مفهوم أساسي: التغييرات التي يتم إجراؤها على الهيكل داخل الدالة **لا** تؤثر على الهيكل الأصلي في الدالة المستدعية، لأن الدالة تعمل مع نسختها الخاصة من البيانات.
هذا النهج مفيد لقراءة أو عرض بيانات الهيكل دون المخاطرة بتعديل الأصل، ولكن نسخ الهياكل الكبيرة قد يكون غير فعال.
جرّب بنفسك
#include <stdio.h>
#include <string.h>
// TODO: قم بتعريف هيكل المستطيل (Rectangle struct) هنا
// TODO: اكتب دالة displayRectangle هنا
// TODO: اكتب دالة modifyRectangle هنا
int main() {
// قراءة المدخلات
int width, height;
char color[15];
scanf("%d", &width);
scanf("%d", &height);
scanf("%s", color);
// TODO: قم بإنشاء متغير المستطيل (Rectangle) وتعيين قيم المدخلات له
// TODO: اطبع "Original rectangle:" واستدعِ دالة displayRectangle
// TODO: استدعِ دالة modifyRectangle
// TODO: اطبع "After modifyRectangle call:" واستدعِ دالة displayRectangle مرة أخرى
return 0;
}يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Logic & Flow
1أساسيات المؤشرات
ما هو المؤشر؟الإعلان عن المؤشراتعامل العنوان (&)عامل إلغاء المرجعية (*)مؤشرات NULLمراجعة: أساسيات المؤشرات4مشروع: أداة نصوص بسيطة
نظرة عامة على المشروععد الأحرف2المؤشرات والمصفوفات
أسماء المصفوفات كمؤشراتعناصر المصفوفة - المؤشراتالعمليات الحسابية على المؤشراتمقارنة المؤشراتمراجعة: التنقل في المصفوفة باستخدام المؤشرات5المؤشرات والدوال
التمرير بالقيمةتمرير المؤشرات إلى الدوالتعديل المتغيرات عبر المؤشراتمثال كلاسيكي: التبديلتمرير المصفوفات إلى الدوالملخص: وسائط المؤشرات في الدوال8الهياكل والمؤشرات
المؤشرات إلى الهياكلعامل السهم (->)تمرير الهياكل بالقيمةتمرير مؤشرات الهياكلالتخصيص الديناميكي للهياكلمراجعة: تعديل الهياكل باستخدام المؤشرات11تحديات المراجعة النهائية
مراجعة: دمج السلاسل النصية الديناميكيمراجعة: مصفوفة من الـ Structsمراجعة: عداد تكرار الكلمات3مصفوفات الأحرف والسلاسل النصية
السلاسل النصية كمصفوفات charالمُنهي الصفري (Null Terminator)إدخال السلاسل النصية باستخدام scanfاستخدام strlen()استخدام strcpy()استخدام strcat()استخدام strcmp()مراجعة: دوال السلاسل النصية الأساسية