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

تمرير الدوال كوسطاء

جزء من قسم 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 نفسها نتائج مختلفة بناءً على الدالة التي نمررها. هذا النمط أساسي لكتابة كود مرن وقابل لإعادة الاستخدام — فأنت تكتب الهيكل مرة واحدة، ويقوم مستخدمو دالتك بتوفير المنطق المحدد الذي يحتاجون إليه.

challenge icon

التحدي

سهل

اكتب دالة apply_twice تأخذ عددين صحيحين ورمز عملية، وتطبق العملية على الأرقام مرتين بالتتابع، ثم تعيد النتيجة النهائية.

ستتلقى دالتك رمز عملية يحدد العملية التي يجب استخدامها. يجب عليك تعريف دوال العمليات داخل الحل الخاص بك وتمريرها إلى دالة مساعدة compute تقبل مؤشر دالة (function pointer).

الهيكل المطلوب:

  • قم بتعريف typedef يسمى Operation لمؤشر دالة يأخذ معاملين من نوع int ويعيد int
  • قم بتعريف دالتين للعمليات: add (تعيد a + b) و multiply (تعيد a * b)
  • قم بتعريف دالة compute تأخذ عددين صحيحين ومؤشر دالة من نوع Operation، ثم تعيد نتيجة استدعاء العملية
  • في apply_twice، اختر العملية المناسبة بناءً على الرمز، ثم استخدم compute مرتين: الأولى مع الأرقام الأصلية، والثانية مع النتيجة والرقم الثاني مرة أخرى

المنطق:

  1. اختر دالة العملية بناءً على op_code (1 = add، 2 = multiply)
  2. استدعِ compute(a, b, operation) للحصول على نتيجة وسيطة
  3. استدعِ compute(intermediate, b, operation) للحصول على النتيجة النهائية
  4. أعد النتيجة النهائية

المعاملات:

  • 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) {
    // اكتب الكود هنا
}
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming