函数指针就是指向函数的指针,其值就是函数体的首地址。在底层,函数名就代表函数的首地址,所以把函数名直接指派给一个同类型的函数指针而不需要&运算符,可以直接用函数名注册回调函数
  调用的方式1 2 3 4 5 size_t (*pf)(const  char *) = &strlen ;int  len = strlen ("hehe" );len = (*pf)("hehe" ); len = pf("hehe" ); 
第一句简单地使用名字strlen直接调用函数,实际上执行过程是函数名strlen首先被转换成一个函数指针,该指针指向内存中函数的位置,然后函数调用操作符调用该函数,执行开始于这个地址的代码 第二句对pf执行间接访问操作,它把函数指针转换为一个函数名。这个转换并不真正需要,编译器在执行函数调用操作符之前又会把它转换回去 第三句和直接通过函数指针访问,这三句在效果上都是一样的
  两段有意思的代码1 2 3 4 5 (*(void (*)())0 )(); void (*signal(int , void (*)(int )))(int );
首先代码一(*(void(*)())0)()把(void(*)())0单独拿出来这是将int类型的0强转成void(*)()函数指针类型,然后在解引用,最后对函数指针解引用后调用 用typedef简化:typedef void(*pFuc)();(*(pFuc)0)(); // 代码一等价于这个形式
再来看看代码二void(*signal(int, void(*)(int)))(int);把signal(int, void(*)(int))单独拿出来,发现这是一个函数名为signal,形参为一个int类型和一个void(*)(int)的函数指针类型,外面的一层void(* )(int)是修饰其返回值类型的 用typedef简化:typedef int(*pFuc)(int);pfuc signal(int, pFuc);
  应用场景  回调函数函数指针变量可以作为某个函数的参数来使用的,回调函数就是一个通过函数指针调用的函数 这里给出一段改进版的冒泡排序,可以做到一份代码同时实现升序和降序两种功能:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 typedef  int (*Comp) (int , int )  ;void  Swap (int * a, int * b)   {    int  t = *a;     *a = *b;     *b = t; } int  Greater (int  a, int  b)   {    return  a > b; } int  Less (int  a, int  b)   {    return  a < b; } void  BubbleSort (int * arr, int  size , Comp p)   {    for  (int  i = 0 ; i < size ; ++i) {         for  (int  j = 0 ; j < size  - 1  - i; ++j) {             if  (p(arr[j + 1 ], arr[j])) {                 Swap(&arr[j], &arr[j + 1 ]);             }         }     } } int  main ()   {    int  a[5 ] = { 1999 , 723 , 1007 , 2019 , 1212  };     BubbleSort(a, 5 , Greater);      for  (int  i = 0 ; i < 5 ; ++i) {         printf ("%d " , a[i]);     }     putchar ('\n' );     BubbleSort(a, 5 , Less);      for  (int  i = 0 ; i < 5 ; ++i) {         printf ("%d " , a[i]);     }     putchar ('\n' );     return  0 ; } 
  转移表转移表就是一个函数指针数组,可以降低函数的圈复杂度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 int  Add (int  a, int  b)   {    return  a + b; } int  Sub (int  a, int  b)   {    return  a - b; } int  Mul (int  a, int  b)   {    return  a * b; } int  Div (int  a, int  b)   {    return  a / b; } int  Menu ()   {    int  input;     printf ("=======================\n" );     printf ("1.Add 2.Sub 3.Mul 4.Div\n" );     printf ("=======================\n" );     printf ("输入选择:" );     scanf ("%d" , &input);     return  input; } int  main ()   {    int  x, y;     typedef  int (*pFuc) (int , int )  ;     pFuc arr[5 ] = { 0 , Add, Sub, Mul, Div };     int  choice = Menu();     printf ("输入操作数:" );     scanf ("%d %d" , &x, &y);     printf ("结果为%d\n" , arr[choice](x, y));     return  0 ; }