استخدام Typedef لمؤشرات الدوال
جزء من قسم البرمجة كائنية التوجه في رحلة C على Coddy. الدرس 35 من 61.
كما رأيت، قد يصعب قراءة تصريحات مؤشرات الدوال. عندما تحتاج إلى استخدام نوع مؤشر الدالة نفسه في مواضع متعددة، تصبح الصياغة متكررة وعُرضة للأخطاء. وهنا يأتي typedef للإنقاذ.
تتيح لك الكلمة المفتاحية typedef إنشاء alias لأي نوع، بما في ذلك مؤشرات الدوال. وبدلاً من كتابة التصريح الكامل في كل مرة، يمكنك تعريف النوع مرة واحدة واستخدام alias في كامل الشيفرة.
إليك كيفية تحويل إعلان مؤشر دالة إلى typedef:
// بدون typedef (فوضوي):
int (*operation)(int, int);
// مع typedef (نظيف):
typedef int (*Operation)(int, int);
Operation op; // أنظف بكثير!تُحاكي الصياغة إعلان مؤشر دالة عاديًا، ولكن مع وجود typedef في البداية. يصبح الاسم الذي تختاره (وهو Operation هنا) نوعًا جديدًا يمثّل «مؤشرًا إلى دالة تأخذ عددين صحيحين وتُرجع عددًا صحيحًا».
الآن يمكنك استخدام هذا النوع في أي مكان:
typedef int (*Operation)(int, int);
int add(int a, int b) { return a + b; }
int multiply(int a, int b) { return a * b; }
int main() {
Operation op1 = add;
Operation op2 = multiply;
printf("%d\n", op1(3, 4)); // المخرجات: 7
printf("%d\n", op2(3, 4)); // المخرجات: 12
return 0;
}يكون هذا الأسلوب ذا قيمة خاصة عند تمرير مؤشرات function باعتبارها parameters أو تخزينها في الهياكل: وهي مواقف ستواجهها بشكل متكرر بينما نمضي نحو تعدد الأشكال.
التحدي
سهللنتدرّب على استخدام typedef لإنشاء اسم مستعار clean لنوع مؤشر دالة comparison. ستعرّف نوعًا يمثّل دالة تقارن عددين صحيحين، ثم تستخدمه لتعريف المتغيرات واستدعاء دوال comparison مختلفة.
اكتب برنامجًا يقوم بما يلي:
- ينشئ
typedefباسمComparatorلنوع مؤشر دالة:- يأخذ معاملَي
int - يعيد قيمة من نوع
int(سالبة إذا كان first أصغر، وصفرًا إذا كانا متساويين، وموجبة إذا كان first أكبر)
- يأخذ معاملَي
- يعرّف دالتي comparison:
ascending: تعيد قيمة تشير إلى الترتيب ascending (first - second)descending: تعيد قيمة تشير إلى الترتيب descending (second - first)
- داخل
main، يعرّف متغيرًا من نوعComparator(باستخدام typedef الخاص بك، وليس صياغة مؤشر الدالة الأولية) - يقرأ ثلاث قيم إدخال: عددين صحيحين ورمز ترتيب (1 لـ ascending، و2 لـ descending)
- يسند الدالة appropriate إلى متغير
Comparatorبناءً على رمز الترتيب - يستدعي comparator باستخدام العددين ويطبع result، متبوعًا برسالة تشير إلى القيمة التي ينبغي أن تأتي أولًا
ستتلقى ثلاث قيم إدخال: العدد first، والعدد second، ورمز الترتيب (1 أو 2).
ينبغي أن يعرض الخرج result الخاص بـ comparison، ثم يحدد أي عدد يأتي أولًا بناءً على إشارة result:
Result: -5
First: 3في هذا المثال، مع قيم الإدخال 3 و8 و1 (ترتيب ascending): يعيد comparison القيمة 3 - 8 = -5 (القيمة السالبة تعني أن العدد first يأتي أولًا في ترتيب ascending)، لذلك نطبع First: 3.
بالنسبة إلى السطر "First":
- إذا كانت result سالبة أو صفرًا، اطبع عدد الإدخال first
- إذا كانت result موجبة، اطبع عدد الإدخال second
الممارسة الأساسية هنا هي استخدام typedef Comparator لتعريف المتغير بطريقة clean، بدلًا من كتابة صياغة مؤشر الدالة الكاملة.
جرّب بنفسك
#include <stdio.h>
// TODO: أنشئ typedef يسمى 'Comparator' لنوع مؤشر دالة
// يأخذ معاملين من نوع int ويُرجع int
// TODO: عرّف دالة المقارنة 'ascending'
// يجب أن تُرجع (first - second)
// TODO: عرّف دالة المقارنة 'descending'
// يجب أن تُرجع (second - first)
int main() {
// اقرأ المدخلات
int num1, num2, orderCode;
scanf("%d", &num1);
scanf("%d", &num2);
scanf("%d", &orderCode);
// TODO: صرّح عن متغير Comparator باستخدام الـ typedef الخاص بك
// TODO: عيّن الدالة المناسبة بناءً على orderCode
// (1 لـ ascending، 2 لـ descending)
// TODO: استدعِ المقارن واحفظ النتيجة
int result;
// اطبع النتيجة
printf("Result: %d\n", result);
// TODO: اطبع أي رقم يأتي أولاً بناءً على النتيجة
// إذا كانت النتيجة سالبة أو صفرًا، اطبع الرقم الأول
// إذا كانت النتيجة موجبة، اطبع الرقم الثاني
printf("First: %d\n", /* منطقك هنا */ 0);
return 0;
}يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1أساسيات البرمجة التركيبية
ملفات الترويسةحواجز التضمينملفات المصدرالدوال الساكنةمراجعة: آلة حاسبة تركيبية4التغليف (Encapsulation)
مفهوم الـ Opaque Pointersتعريف الـ Opaque Structsالـ Getters والـ Settersالتحقق من البيانات في الـ Settersملخص: الصندوق السري7مؤشرات الدوال
التصريح عن مؤشرات الدوالاستدعاء مؤشرات الدوالاستخدام Typedef لمؤشرات الدوالتمرير الدوال كوسطاءمراجعة: Calculator Dispatch2الكائنات والأساليب
الـ Structs ككائناتمؤشر 'Self'صحة استخدام Constالمؤشر مقابل القيمةالأساليب المساعدةملخص: Point Manager5مشروع: حساب بنكي بسيط
إعداد المشروعتنفيذ الحساب3دورة حياة الكائن
نمط المنشئ (Constructor Pattern)نمط الهادم (Destructor Pattern)تهيئة الـ Stackالنسخ العميق (Deep Copy)مراجعة: String Wrapper6الوراثة عبر التركيب
تضمين الـ Structقاعدة العضو الأولالوصول إلى أعضاء الأبعملية الـ Upcastingمراجعة: هرمية الأشكال9مشروع: رسّام الأشكال
نظرة عامة على المشروعتنفيذ الدائرةتنفيذ المستطيلاستخدام تعدد الأشكالحاوية الأشكالتدرّب بنفسك: مترجم C عبر الإنترنت