تعريف مؤشّر دالة
مثل أي مؤشّر، لكنه يخزّن عنوان دالة بدل متغيّر:
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)(دالة تُرجع مؤشّر).
🎯 التالي: خلاصة المسار.