|
像正常的数据指针(int *,char *等),我们可以有函数指针。 下面是一个简单的例子,显示使用函数指针的声明和函数调用。
- #include <stdio.h>
- // A normal function with an int parameter
- // and void return type
- void fun(int a)
- {
- printf("Value of a is %d\n", a);
- }
-
- int main()
- {
- // fun_ptr is a pointer to function fun()
- void (*fun_ptr)(int) = &fun;
-
- /* The above line is equivalent of following two
- void (*fun_ptr)(int);
- fun_ptr = &fun;
- */
-
- // Invoking fun() using fun_ptr
- (*fun_ptr)(10);
-
- return 0;
- }
复制代码 输出:为什么我们需要在上面的例子中像fun_ptr这样的函数指针加一个括号?如果我们删除括号,则表达式
变成它是一个返回void指针的函数的声明。 有关详细信息,请参阅以下帖子。
如何声明一个指向一个函数的指针?
以下是一些有关函数指针的有趣事实。- 与正常指针不同,函数指针指向代码,而不是数据。 通常,函数指针存储可执行代码的开始地址。
- 与正常指针不同,我们不使用函数指针去分配内存。
- 函数名也可用于获取函数地址。例如,在下面的程序中,我们已删除地址运算符'&'。我们也通过删除*改变了函数调用,程序仍然工作。
- #include <stdio.h>
- // A normal function with an int parameter
- // and void return type
- void fun(int a)
- {
- printf("Value of a is %d\n", a);
- }
-
- int main()
- {
- void (*fun_ptr)(int) = fun; // & removed
-
- fun_ptr(10); // * removed
-
- return 0;
- }
复制代码 输出:
- 像普通指针一样,我们可以有一个函数指针数组。
- 函数指针可用于switch case。例如,在下面的程序中,用户被要求在0到2之间选择做不同的任务。
- #include <stdio.h>
- void add(int a, int b)
- {
- printf("Addition is %d\n", a+b);
- }
- void subtract(int a, int b)
- {
- printf("Subtraction is %d\n", a-b);
- }
- void multiply(int a, int b)
- {
- printf("Multiplication is %d\n", a*b);
- }
-
- int main()
- {
- // fun_ptr_arr is an array of function pointers
- void (*fun_ptr_arr[])(int, int) = {add, subtract, multiply};
- unsigned int ch, a = 15, b = 10;
-
- printf("Enter Choice: 0 for add, 1 for subtract and 2 "
- "for multiply\n");
- scanf("%d", &ch);
-
- if (ch > 2) return 0;
-
- (*fun_ptr_arr[ch])(a, b);
-
- return 0;
- }
复制代码- Enter Choice: 0 for add, 1 for subtract and 2 for multiply
- 2
- Multiplication is 150
复制代码- 像正常的数据指针一样,函数指针可以作为参数传递,也可以从函数中返回。例如,象下面的C程序,wrapper()接收到一个void fun()作为参数数
- // A simple C program to show function pointers as parameter
- #include <stdio.h>
-
- // Two simple functions
- void fun1() { printf("Fun1\n"); }
- void fun2() { printf("Fun2\n"); }
-
- // A function that receives a simple function
- // as parameter and calls the function
- void wrapper(void (*fun)())
- {
- fun();
- }
-
- int main()
- {
- wrapper(fun1);
- wrapper(fun2);
- return 0;
- }
复制代码 这一点在C中特别有用,我们可以使用函数指针来避免代码冗余。
- // An example for qsort and comparator
- #include <stdio.h>
- #include <stdlib.h>
-
- // A sample comparator function that is used
- // for sorting an integer array in ascending order.
- // To sort any array for any other data type and/or
- // criteria, all we need to do is write more compare
- // functions. And we can use the same qsort()
- int compare (const void * a, const void * b)
- {
- return ( *(int*)a - *(int*)b );
- }
-
- int main ()
- {
- int arr[] = {10, 5, 15, 12, 90, 80};
- int n = sizeof(arr)/sizeof(arr[0]), i;
-
- qsort (arr, n, sizeof(int), compare);
-
- for (i=0; i<n; i++)
- printf ("%d ", arr[i]);
- return 0;
- }
复制代码 输出:象qsort()相似,我们可以编写自己的函数,可用于任何类型的数据,可以做不同的任务没有冗余代码
- #include <stdio.h>
- #include <stdbool.h>
-
- // A compare function that is used for searching an integer
- // array
- bool compare (const void * a, const void * b)
- {
- return ( *(int*)a == *(int*)b );
- }
-
- // General purpose search() function that can be used
- // for searching an element *x in an array arr[] of
- // arr_size. Note that void pointers are used so that
- // the function can be called by passing a pointer of
- // any type. ele_size is size of an array element
- int search(void *arr, int arr_size, int ele_size, void *x,
- bool compare (const void * , const void *))
- {
- // Since char takes one byte, we can use char pointer
- // for any type/ To get pointer arithmetic correct,
- // we need to multiply index with size of an array
- // element ele_size
- char *ptr = (char *)arr;
-
- int i;
- for (i=0; i<arr_size; i++)
- if (compare(ptr + i*ele_size, x))
- return i;
-
- // If element not found
- return -1;
- }
-
- int main()
- {
- int arr[] = {2, 5, 7, 90, 70};
- int n = sizeof(arr)/sizeof(arr[0]);
- int x = 7;
- printf ("Returned index is %d ", search(arr, n,
- sizeof(int), &x, compare));
- return 0;
- }
复制代码 输出:
上述搜索函数可以通过编写单独的自定义compare()来用于任何数据类型。
参考:
[url=httphttp://www.cs.cmu.edu/%7Eab/15-1 ... pdfnote.youdao.com/]http://www.cs.cmu.edu/~ab/15-123S11/AnnotatedNotes/Lecture14.pdf[/url]
http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-087-practical-programming-in-c-january-iap-2010/lecture-notes/MIT6_087IAP10_lec08.pdf
http://www.cs.cmu.edu/~guna/15-123S11/Lectures/Lecture14.pdf
本文由Abhay Rathi提供。
|
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|