0Pricing
C++ Academy · درس

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

مرّر الدوال كمعاملات

مؤشرات الدوال درس مجاني في C++ Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C++ Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C++ Academy 4 دروس في المجموع.

ما مؤشر الدالة؟

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

  • يشفّر النوع التوقيع.
  • يتيح للدوال تلقي السلوك كوسيط.
#include <iostream>

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

int main() {
    int (*op)(int, int) = add;
    std::cout << op(3, 4) << '\n';
    return 0;
}

التصريح بالنوع

يُقرأ التصريح int (*op)(int, int) على النحو التالي: إن op مؤشر إلى دالة تستقبل عددين صحيحين وتعيد عددًا صحيحًا. والأقواس المحيطة بـ *op مطلوبة.

#include <iostream>

int square(int x) { return x * x; }

int main() {
    int (*fn)(int) = square;
    std::cout << fn(5) << '\n';
    return 0;
}

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

يُستدعى مؤشر الدالة تمامًا مثل الدالة نفسها. ويمكنك أيضًا إلغاء الإشارة إليه صراحةً، لكن ذلك نادرًا ما يكون ضروريًا.

#include <iostream>

void greet() { std::cout << "Hello\n"; }

int main() {
    void (*g)() = greet;
    g();
    (*g)();
    return 0;
}

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

يمكن للدالة قبول وسيط من نوع مؤشر دالة، مما يتيح للمستدعي إدخال سلوك مخصص.

#include <iostream>

int apply(int x, int (*fn)(int)) { return fn(x); }
int doubler(int n) { return n * 2; }

int main() {
    std::cout << apply(10, doubler) << '\n';
    return 0;
}

الاختيار أثناء التشغيل

بما أن مؤشر الدالة متغير، يمكنك تحديد الدالة التي سيُستدعى بها البرنامج أثناء تشغيله.

#include <iostream>

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

int main() {
    bool wantAdd = true;
    int (*op)(int, int) = wantAdd ? add : sub;
    std::cout << op(8, 3) << '\n';
    return 0;
}

مصفوفات مؤشرات الدوال

خزّن عدة مؤشرات دوال في مصفوفة لإنشاء جدول توجيه بسيط يُفهرس باستخدام قيمة.

#include <iostream>

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

int main() {
    int (*ops[2])(int, int) = {add, mul};
    std::cout << ops[0](2, 3) << ' ' << ops[1](2, 3) << '\n';
    return 0;
}

استخدام typedef

صياغة المؤشر معقدة ومليئة بالرموز. يتيح الاسم البديل باستخدام typedef أو using منح النوع اسمًا سهل القراءة.

#include <iostream>

using BinOp = int(*)(int, int);
int add(int a, int b) { return a + b; }

int main() {
    BinOp op = add;
    std::cout << op(6, 7) << '\n';
    return 0;
}

مؤشرات الدوال مع الخوارزميات

تقبل الخوارزميات القياسية الكيانات القابلة للاستدعاء، وتصلح الدالة العادية لأداء هذا الدور. وهنا تُستخدم دالة شرطية لعدّ الأعداد الزوجية.

#include <iostream>
#include <vector>
#include <algorithm>

bool isEven(int n) { return n % 2 == 0; }

int main() {
    std::vector<int> v = {1, 2, 3, 4, 5, 6};
    int c = std::count_if(v.begin(), v.end(), isEven);
    std::cout << "Evens: " << c << '\n';
    return 0;
}

القيد: لا توجد حالة

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

#include <iostream>

int counter = 0;
int next() { return ++counter; }

int main() {
    int (*fn)() = next;
    std::cout << fn() << ' ' << fn() << ' ' << fn() << '\n';
    return 0;
}

تحويل لامبدا غير الملتقطة

يمكن لامبدا لا تلتقط شيئًا أن تتحول ضمنيًا إلى مؤشر دالة مطابق، وهو أمر مفيد للدوال الصغيرة المضمّنة.

#include <iostream>

int main() {
    int (*fn)(int) = [](int x) { return x + 100; };
    std::cout << fn(1) << '\n';
    return 0;
}

مؤشرات الدوال الفارغة

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

#include <iostream>

int main() {
    int (*fn)(int) = nullptr;
    if (fn) {
        std::cout << fn(5) << '\n';
    } else {
        std::cout << "No function set\n";
    }
    return 0;
}

اختبار سريع

اختبر مدى فهمك لقيود مؤشرات الدوال.

مراجعة

لقد تعلمت عن مؤشرات الدوال:

  • تحتفظ بعنوان دالة وتُستدعى مثل الدالة
  • تتيح تمرير السلوك كوسيط وإنشاء جداول توجيه
  • تجعل الأسماء البديلة نوعها سهل القراءة
  • لا يمكنها حمل حالة، لكن لامبدا غير الملتقطة تتحول إليها

بعد ذلك ستتعرف على std::function، الذي يمكنه تخزين أي كيان قابل للاستدعاء، بما في ذلك الكيانات ذات الحالة.

الأسئلة الشائعة

هل درس «مؤشرات الدوال» مجاني؟

نعم — نص درس «مؤشرات الدوال» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C++ Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C++ Academy 4 دروس في المجموع.

ماذا ستتعلم في «مؤشرات الدوال»؟

مرّر الدوال كمعاملات تتمرن على C++ Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ C++ Academy؟

لا تُشترط خبرة سابقة. C++ Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.

كم من الوقت يستغرق درس «مؤشرات الدوال»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس C++ Academy هذا؟

نعم. كل درس في C++ Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. مؤشرات الدوال
  2. std::function
  3. std::bind
  4. اختيار الكائنات القابلة للاستدعاء
← العودة إلى C++ Academy