تمرير الدوال كوسطاء
جزء من قسم Object Oriented Programming في رحلة C على Coddy — الدرس 36 من 61.
أحد أقوى استخدامات مؤشرات الدوال (function pointers) هو تمريرها كوسطاء لدوال أخرى. يتيح لك ذلك حقن سلوك مخصص في دالة دون تعديل الكود الخاص بها — وهي تقنية تسمى أحياناً callback.
فكر في دالة تجري عملية حسابية على رقمين. بدلاً من كتابة العملية بشكل ثابت (hardcoding)، يمكنك قبول مؤشر دالة (function pointer) يحدد العملية التي سيتم إجراؤها:
typedef int (*Operation)(int, int);
int compute(int a, int b, Operation op) {
return op(a, b);
}لا تعرف الدالة compute ما إذا كانت تقوم بالجمع أو الطرح أو القيام بشيء آخر تماماً. فهي ببساطة تستدعي أي دالة يتم تمريرها إليها:
int add(int a, int b) { return a + b; }
int multiply(int a, int b) { return a * b; }
int main() {
printf("%d\n", compute(5, 3, add)); // المخرج: 8
printf("%d\n", compute(5, 3, multiply)); // المخرج: 15
return 0;
}لاحظ كيف تنتج دالة compute نفسها نتائج مختلفة بناءً على الدالة التي نمررها. هذا النمط أساسي لكتابة كود مرن وقابل لإعادة الاستخدام — فأنت تكتب الهيكل مرة واحدة، ويقوم مستخدمو دالتك بتوفير المنطق المحدد الذي يحتاجون إليه.
التحدي
سهلاكتب دالة apply_twice تأخذ عددين صحيحين ورمز عملية، وتطبق العملية على الأرقام مرتين بالتتابع، ثم تعيد النتيجة النهائية.
ستتلقى دالتك رمز عملية يحدد العملية التي يجب استخدامها. يجب عليك تعريف دوال العمليات داخل الحل الخاص بك وتمريرها إلى دالة مساعدة compute تقبل مؤشر دالة (function pointer).
الهيكل المطلوب:
- قم بتعريف
typedefيسمىOperationلمؤشر دالة يأخذ معاملين من نوعintويعيدint - قم بتعريف دالتين للعمليات:
add(تعيد a + b) وmultiply(تعيد a * b) - قم بتعريف دالة
computeتأخذ عددين صحيحين ومؤشر دالة من نوعOperation، ثم تعيد نتيجة استدعاء العملية - في
apply_twice، اختر العملية المناسبة بناءً على الرمز، ثم استخدمcomputeمرتين: الأولى مع الأرقام الأصلية، والثانية مع النتيجة والرقم الثاني مرة أخرى
المنطق:
- اختر دالة العملية بناءً على
op_code(1 = add، 2 = multiply) - استدعِ
compute(a, b, operation)للحصول على نتيجة وسيطة - استدعِ
compute(intermediate, b, operation)للحصول على النتيجة النهائية - أعد النتيجة النهائية
المعاملات:
a(int): الرقم الأولb(int): الرقم الثانيop_code(int): رمز العملية (1 لـ add، 2 لـ multiply)
المخرجات: النتيجة بعد تطبيق العملية مرتين بالتتابع (int)
مثال: مع a = 5، b = 3، op_code = 1 (add):
- الحساب الأول: 5 + 3 = 8
- الحساب الثاني: 8 + 3 = 11
- النتيجة: 11
مع a = 2، b = 4، op_code = 2 (multiply):
- الحساب الأول: 2 × 4 = 8
- الحساب الثاني: 8 × 4 = 32
- النتيجة: 32
ورقة مرجعية
يمكن تمرير مؤشرات الدوال كوسطاء لدوال أخرى، مما يتيح **الاستدعاءات الراجعة (callbacks)** — وهي طريقة لحقن سلوك مخصص دون تعديل كود الدالة.
عرّف نوع مؤشر دالة باستخدام typedef:
typedef int (*Operation)(int, int);أنشئ دالة تقبل مؤشر دالة كمعامل:
int compute(int a, int b, Operation op) {
return op(a, b);
}مرر دوالاً مختلفة لتحقيق سلوكيات مختلفة:
int add(int a, int b) { return a + b; }
int multiply(int a, int b) { return a * b; }
int main() {
printf("%d\n", compute(5, 3, add)); // المخرجات: 8
printf("%d\n", compute(5, 3, multiply)); // المخرجات: 15
return 0;
}يتيح لك هذا النمط كتابة كود مرن وقابل لإعادة الاستخدام حيث يتم تعريف الهيكل مرة واحدة ويقوم المستخدمون بتوفير المنطق المحدد الذي يحتاجون إليه.
جرّب بنفسك
int apply_twice(int a, int b, int op_code) {
// اكتب الكود هنا
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Object Oriented Programming
1أساسيات البرمجة التركيبية
ملفات الترويسةحواجز التضمينملفات المصدرالدوال الساكنةمراجعة: آلة حاسبة تركيبية4التغليف (Encapsulation)
مفهوم الـ Opaque Pointersتعريف الـ Opaque Structsالـ Getters والـ Settersالتحقق من البيانات في الـ Settersملخص: الصندوق السري7مؤشرات الدوال
التصريح عن مؤشرات الدوالاستدعاء مؤشرات الدوالاستخدام Typedef لمؤشرات الدوالتمرير الدوال كوسطاءمراجعة: Calculator Dispatch2الكائنات والأساليب
الـ Structs ككائناتمؤشر 'Self'صحة استخدام Constالمؤشر مقابل القيمةالأساليب المساعدةملخص: Point Manager5مشروع: حساب بنكي بسيط
إعداد المشروعتنفيذ الحساب3دورة حياة الكائن
نمط المنشئ (Constructor Pattern)نمط الهادم (Destructor Pattern)تهيئة الـ Stackالنسخ العميق (Deep Copy)مراجعة: String Wrapper6الوراثة عبر التركيب
تضمين الـ Structقاعدة العضو الأولالوصول إلى أعضاء الأبعملية الـ Upcastingمراجعة: هرمية الأشكال9مشروع: رسّام الأشكال
نظرة عامة على المشروعتنفيذ الدائرة