تخطَّ إلى المحتوى

🇨 شرح لغة C

مؤشّرات الدوال

الدرس 28 من 29· ⏱ 2 دقائق قراءة

تعريف مؤشّر دالة

مثل أي مؤشّر، لكنه يخزّن عنوان دالة بدل متغيّر:

int add(int a, int b) { return a + b; }

int (*op)(int, int) = add;   // op يشير للدالة add
printf("%d\n", op(2, 3));    // 5 — استدعاء عبر المؤشّر

النوع int (*)(int, int) يعني: مؤشّر لدالة تأخذ int, int وتُرجع int.

تمرير دالة كمعامل (Callback)

int apply(int (*fn)(int, int), int a, int b) {
    return fn(a, b);   // تنفّذ الدالة التي مُرِّرت
}

int mul(int a, int b) { return a * b; }
printf("%d\n", apply(mul, 4, 5));   // 20

هذا أساس بناء دوال عامّة تقبل سلوكًا مخصّصًا من المستدعي — مثل دوال الترتيب.

qsort من المكتبة القياسية

qsort تفرز أي مصفوفة، ونحن نزوّدها بدالة مقارنة (comparator) تحدّد الترتيب:

#include <stdlib.h>

int compareInts(const void *a, const void *b) {
    int x = *(const int *)a;
    int y = *(const int *)b;
    return x - y;   // سالب: x قبل y، صفر: متساويان، موجب: x بعد y
}

int nums[] = {5, 2, 8, 1};
qsort(nums, 4, sizeof(int), compareInts);
// nums الآن: {1, 2, 5, 8}
  • المعامل الأول: مؤشّر لبداية المصفوفة (void* — تعمل مع أي نوع).
  • الثاني: عدد العناصر.
  • الثالث: حجم العنصر الواحد بالبايت (sizeof).
  • الرابع: دالة المقارنة، توقيعها دائمًا int (*)(const void*, const void*).

💡 داخل دالة المقارنة حوّل const void* إلى النوع الحقيقي قبل قراءة القيمة — qsort لا تعرف نوع عناصرك، هذا سبب وجود void*.

أخطاء شائعة

  • نسيان تحويل (cast) المعاملات من const void* داخل دالة المقارنة.
  • توقيع خاطئ لدالة المقارنة (لازم يطابق int (*)(const void*, const void*) تمامًا).
  • الخلط بين int (*p)(int) (مؤشّر دالة) وint *p(int) (دالة تُرجع مؤشّر).

🎯 التالي: خلاصة المسار.

شرح مؤشّرات الدوال — لغة C بالعربي
مؤشّرات الدواللغة C بالعربي · The Code Fix

📚 لمزيد من التعمّق في لغة C، راجِع مرجع لغة C الرسمي.

هل كان هذا الدرس مفيدًا؟