تمرير الدوال كوسطاء
جزء من قسم البرمجة كائنية التوجه في رحلة C على Coddy. الدرس 36 من 61.
من أكثر استخدامات مؤشرات الدوال قوةً تمريرها كوسائط إلى دوال أخرى. يتيح لك ذلك حقن سلوك مخصّص في دالة دون تعديل شيفرتها: وهي تقنية تُسمّى أحيانًا استدعاءً عكسيًا.
تخيّل دالةً تُجري عملية حسابية على عددين. بدلاً من تضمين العملية بشكل ثابت، يمكنك قبول مؤشّر دالة يحدّد العملية التي يجب إجراؤها:
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 تقبل مؤشراً إلى دالة.
ملاحظة: لا حاجة إلا إلى الدوال. تستدعي الاختبارات apply_twice مباشرةً وتتحقق من القيمة التي تُرجعها، لذا لا تقرأ المدخلات ولا تطبع أي شيء.
البنية المطلوبة:
- عرّف
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
جرّب بنفسك
int apply_twice(int a, int b, int op_code) {
// اكتب الكود هنا
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
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مشروع: رسّام الأشكال
نظرة عامة على المشروعتنفيذ الدائرةتنفيذ المستطيلاستخدام تعدد الأشكالحاوية الأشكالتدرّب بنفسك: مترجم C عبر الإنترنت