استدعاء مؤشرات الدوال
جزء من قسم البرمجة كائنية التوجه في رحلة C على Coddy. الدرس 34 من 61.
Now بعد أن عرفت كيفية Declare مؤشر function وAssign function إليه، فإن الخطوة التالية هي فعليًا استدعاء function من خلال ذلك pointer.
البنية النحوية واضحة ومباشرة. تستخدم function pointer تمامًا كما لو كنت تستدعي دالة عادية:
int add(int a, int b) {
return a + b;
}
int main() {
int (*operation)(int, int) = add;
int result = operation(5, 3); // يستدعي add(5, 3)
printf("%d\n", result); // الإخراج: 8
return 0;
}ما عليك سوى كتابة اسم pointer متبوعًا بأقواس تحتوي على الوسائط. تقوم لغة C تلقائيًا بإلغاء إشارة pointer وتنفيذ function التي يشير إليها.
يمكنك أيضًا استخدام صيغة إلغاء الإشارة الصريحة مع (*operation)(5, 3)، لكنها اختيارية وأقل شيوعًا. كلا الشكلين ينتجان نتائج متطابقة.
تظهر القوة الحقيقية عندما تعيد إسناد pointer إلى functions مختلفة:
int subtract(int a, int b) {
return a - b;
}
operation = subtract;
result = operation(5, 3); // الآن يستدعي subtract(5, 3)
printf("%d\n", result); // المخرجات: 2ينفذ المتغير نفسه operation الآن منطقًا مختلفًا تمامًا. وتُعد هذه القدرة على تبديل السلوك في وقت التشغيل أساس تعدد الأشكال في C.
التحدي
سهللنتدرّب على استدعاء functions من خلال المؤشرات وتبديل function التي يتم تنفيذها. ستبني آلة حاسبة بسيطة يمكنها التبديل بين الجمع والطرح أثناء التشغيل.
اكتب برنامجًا يقوم بما يلي:
- يعرّف function اثنتين:
add: تأخذ معاملين من النوعintوتعيد مجموعهماsubtract: تأخذ معاملين من النوعintوتعيد ناتج طرح second من first
- في
main، يعرّف pointer إلى function يُسمىcalcويمكنه الإشارة إلى functions تأخذ معاملين من النوعintوتعيد قيمة من النوعint - يقرأ أربعة inputs: عددين صحيحين واثنين من operation codes
- لكل operation code:
- Assign الـ function appropriate إلى
calc(1 لـ add، و2 لـ subtract) - Call الـ function من خلال pointer باستخدام العددين
- اطبع result
- Assign الـ function appropriate إلى
ستتلقى أربعة inputs: first number، وsecond number، وfirst operation code (1 أو 2)، وsecond operation code (1 أو 2).
يجب أن يُظهر output نتيجتين في سطرين منفصلين: واحدة لكل operation تم تنفيذها باستخدام العددين نفسيهما:
15
5في هذا المثال، مع inputs 10 و5 و1 و2: تقوم العملية الأولى (code 1) بجمع 10 + 5 = 15، ثم تتم إعادة Assign إلى pointer، وتطرح العملية الثانية (code 2) 10 - 5 = 5.
يوضح هذا كيف يمكن لمتغير pointer نفسه تنفيذ منطق مختلف تمامًا من خلال إعادة Assign إليه بين عمليات الاستدعاء.
جرّب بنفسك
#include <stdio.h>
// TODO: عرّف دالة add هنا
// TODO: عرّف دالة subtract هنا
int main() {
// اقرأ المدخلات
int num1, num2, op1, op2;
scanf("%d", &num1);
scanf("%d", &num2);
scanf("%d", &op1);
scanf("%d", &op2);
// TODO: صرّح عن مؤشر دالة يسمى 'calc' يمكنه الإشارة إلى
// دوال تأخذ معاملين من نوع int وتعيد int
// TODO: بالنسبة لرمز العملية الأولى (op1):
// - عيّن الدالة المناسبة إلى calc (1 لـ add، 2 لـ subtract)
// - استدعِ الدالة عبر المؤشر واطبع النتيجة
// TODO: بالنسبة لرمز العملية الثانية (op2):
// - أعد تعيين calc إلى الدالة المناسبة
// - استدعِ الدالة عبر المؤشر واطبع النتيجة
return 0;
}يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
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 عبر الإنترنت