引言
在C语言中有很多这样神奇的存在,正着读和反着读都有意义,比方说常量指针和指针常量,指针函数和函数指针又是什么呢?
这个要从语言学的角度去分析就很好理解哈,可以说是个偏正短语,由定语和中心词构成。
从上图就可以很容易地看出,指针函数,其实质上是一个函数 ,而函数指针,本质上是一个指针 。那么具体是什么样的函数和什么样的指针呢?
1.指针函数
指针函数,指的是返回值是指针的函数,有时候我们出于需要,某个函数的返回值会是一个指针,比方说:
#include <stdio.h> int sum = 0; int *add(int a, int b) { sum = a + b; return ∑ } int main() { int *p = add(2, 3); printf("%d\n", *p); }
这就是常说的指针函数。但是为了保持该地址处的值不会改变,往往会进行这样的处理。
#include <stdio.h> int sum = 0; int *add(int a, int b) { static int sum = 0; sum = a + b; return ∑ } int main() { int *p = add(2, 3); printf("%d\n", *p); }
也就是所谓的static
关键字。这样做的意义,就在于,这样sum
便处在数据段,也就是说,程序运行期间一直存在,并不像局部变量那样,保存在栈区,程序执行完之后就会将该部分内存回收。
2.函数指针
所谓的函数指针,就是指向函数的指针,比方下面的例子;
#include <stdio.h> void func() { printf("hello world in func!"); } int main() { void(*pfunc)(); pfunc = func; pfunc(); }
代码很好理解,定义了函数指针pfunc
指向了func
,这个时候再执行,当然就会直接执行func
。打印输出如下:
或者说,稍微复杂点,可以传参数,像下面这样;
#include <stdio.h> void func(char a[], int len) { printf("hello world in func!\n"); for (int i = 0; i < len; i++) { printf("%c",a[i]); } printf("\n"); } int main() { void(*pfunc)(); pfunc = func; pfunc("^-^",3); }
打印输出:
当然,要想真正发挥函数指针的作用,当然是在回调函数中。函数指针的一个非常典型的应用就是回调函数,比如下面的例子:
#include <stdio.h> //假设此处是冒泡排序的实现函数 void bubble_sort() { printf("this is bubble sort function!\n"); } //假设此处是选择排序的实现函数 void select_sort() { printf("this is quick sort function!\n"); } //假设此处是快速排序的实现函数 void quick_sort() { printf("this is quick sort function!\n"); } //这个函数就是回调函数 void data_handle(void (*pfunc)()) { pfunc(); } int main() { data_handle(quick_sort); data_handle(bubble_sort); data_handle(select_sort); }
假设有这样一个应用场景,
我需要对某数据进行处理,处理之前要进行排序,但我目前并没有想好要采用哪种排序算法。
这个时候就可以采用回调函数来解决这个问题。
打印输出如下;
如果直接写会怎么样呢?
这个时候主函数是直接调用的data_handle()
,然而每次排序算法的改变,都需要自己根据实际情况去在data_handle()
调用不同的排序算法,这样对于真个程序的架构来说,显然是不够友好的,一般在大型程序开发中,底层的函数写好以后,是不允许随便修改的,这个时候回调函数就起到了很好的作用。