البارحة قرأت عن المؤشرات إلى الدوال (Pointer to functions) (أو الدوال المؤشريه :D ) و احببت أن أشارككم ما قرأت..
المؤشرات للدوال ميزه موجوده في لغه ال سي .. و هي ميزه مهمه لأن لها عدة إستخدامات ... سنتطرق لمثال لإستخدامها في نهاية الدُريس :D
تعريف مؤشر على دالة:
كما نعرف أنه لتعريف مؤشر على متغير فإننا نستخدم :
int* ptr_to_int;
أما لتعريف مؤشر على دالة فإننا نستخدم:
return_type (*ptr_to_func) (param_list);
مثلا:
int (*execute) (char* );
هذا بالنسبة للتعريف... اما بالنسبة لل initialization , فإننا نستخدم الشكل التالي:
execute = func_name;
حيث أن func_name هي دالة لها الشكل التالي:
int func_name (char*);
أي أن الدالة func_name يجب (أعتقد ذلك) أن يكون لها نفس ال signature للمؤشر على الدالة....
أما بالنسبة لإستخدام المؤشر على الدالة:
فإنه يستخدم لتنفيذ الدالة التي يشير عليها....
فإن :
execute("select * from employees;");يقوم بتنفيذ الدالة func_name ...
التطبيقات
هناك أكثر من تطبيق للمؤشر على الدوال... مثلا المستخدم في الدالة qsort في stdlib.h
لكن هنا, سأتحدث عن تطبيق أخر للمؤشرات على الدوال.... و هو إستخدامها لعمل corss-cutting للكود ... او بما بيمثل شكل بيسط من أشكال ال Aspect-oriented programming (AOP):
(نستخدم في الجافا Dynamic proxies + reflection للحصول على مثل هذا العمل..... فعمل هذا في السي أيسر :D )
أترككم مع المثال:
#include <stdio.h>
void sql_insert(char*);
void sql_update(char*);
void sql_delete(char*);
void sql_select(char*);
void do_database_task(void (*sql_query) (char*), char*);
int main(void)
{
do_database_task(sql_select , "SELECT * FROM employees");
printf("\n");
do_database_task(sql_delete , "DELETE FROM employees");
return 0;
}
void sql_insert(char *query)
{
printf("Executing insert query: %s\n", query);
}
void sql_update(char *query)
{
printf("Executing update query: %s\n", query);
}
void sql_delete(char *query)
{
printf("Executing delete query: %s\n", query);
}
void sql_select(char *query)
{
printf("Executing select query: %s\n", query);
}
void do_database_task(void (*sql_query) (char*), char* query)
{
printf("openning connection ....\n");
sql_query(query);
printf("closing connection ....\n");
}