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

استدعاء مؤشرات الدوال

جزء من قسم Object Oriented Programming في رحلة C على Coddy — الدرس 34 من 61.

الآن بعد أن عرفت كيفية التصريح عن مؤشر دالة وتعيين دالة له، فإن الخطوة التالية هي استدعاء الدالة فعلياً من خلال ذلك المؤشر.

الصيغة بسيطة ومباشرة — يمكنك استخدام مؤشر الدالة (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;
}

ببساطة، اكتب اسم المؤشر متبوعاً بأقواس تحتوي على الوسائط. تقوم لغة C تلقائياً بإلغاء إسناد المؤشر وتنفيذ الدالة التي يشير إليها.

يمكنك أيضًا استخدام صيغة إلغاء المرجع الصريحة مع (*operation)(5, 3)، لكنها اختيارية وأقل شيوعًا. كلا الشكلين ينتجان نتائج متطابقة.

تظهر القوة الحقيقية عندما تعيد تعيين المؤشر إلى دوال مختلفة:

int subtract(int a, int b) {
    return a - b;
}

operation = subtract;
result = operation(5, 3);  // يستدعي الآن subtract(5, 3)
printf("%d\n", result);    // المخرجات: 2

نفس المتغير operation ينفذ الآن منطقاً مختلفاً تماماً. هذه القدرة على تبديل السلوك في وقت التشغيل هي أساس تعدد الأشكال (polymorphism) في لغة C.

challenge icon

التحدي

سهل

دعونا نتدرب على استدعاء الدوال من خلال المؤشرات (pointers) وتبديل الدالة التي يتم تنفيذها. ستقوم ببناء آلة حاسبة بسيطة يمكنها التبديل بين الجمع والطرح أثناء وقت التشغيل.

اكتب برنامجاً يقوم بما يلي:

  1. تعريف دالتين:
    • add — تأخذ معاملين من نوع int وتعيد مجموعهما
    • subtract — تأخذ معاملين من نوع int وتعيد ناتج طرح الثاني من الأول
  2. في الدالة main، قم بالتصريح عن مؤشر دالة يسمى calc يمكنه الإشارة إلى دوال تأخذ معاملين من نوع int وتعيد قيمة من نوع int
  3. قراءة أربعة مدخلات: عددين صحيحين ورمزين للعمليات
  4. لكل رمز عملية:
    • تعيين الدالة المناسبة للمؤشر calc (1 للجمع add، و 2 للطرح subtract)
    • استدعاء الدالة من خلال المؤشر مع العددين
    • طباعة النتيجة

ستتلقى أربعة مدخلات: العدد الأول، العدد الثاني، رمز العملية الأول (1 أو 2)، و رمز العملية الثاني (1 أو 2).

يجب أن يظهر مخرجك نتيجتين في سطرين منفصلين — نتيجة لكل عملية تم إجراؤها باستخدام نفس العددين:

15
5

في هذا المثال، مع المدخلات 10، 5، 1، 2: العملية الأولى (الرمز 1) تجمع 10 + 5 = 15، ثم يتم إعادة تعيين المؤشر، والعملية الثانية (الرمز 2) تطرح 10 - 5 = 5.

يوضح هذا كيف يمكن لمتغير المؤشر نفسه تنفيذ منطق مختلف تماماً عن طريق إعادة تعيينه بين الاستدعاءات.

ورقة مرجعية

لاستدعاء دالة من خلال مؤشر، استخدم اسم المؤشر متبوعاً بأقواس تحتوي على الوسائط:

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;
}

يمكنك أيضاً استخدام صيغة إلغاء المرجعية الصريحة (*operation)(5, 3)، لكنها اختيارية.

يمكن إعادة تعيين مؤشرات الدوال للإشارة إلى دوال مختلفة أثناء وقت التشغيل:

int subtract(int a, int b) {
    return a - b;
}

operation = subtract;
result = operation(5, 3);  // يستدعي الآن subtract(5, 3)
printf("%d\n", result);    // المخرج: 2

يسمح هذا لمتغير المؤشر نفسه بتنفيذ منطق مختلف عن طريق إعادة تعيينه بين الاستدعاءات.

جرّب بنفسك

#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 للجمع، 2 للطرح)
    // - استدعِ الدالة من خلال المؤشر واطبع النتيجة
    
    
    // TODO: بالنسبة لرمز العملية الثاني (op2):
    // - أعد تعيين calc للدالة المناسبة
    // - استدعِ الدالة من خلال المؤشر واطبع النتيجة
    
    
    return 0;
}
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming