1 函数指针

1.1 函数类型

通过什么来区分两个不同的函数?
一个函数在编译时被分配一个入口地址,这个地址就称为函数的指针,函数名代表函数的入口地址。

函数三要素: 名称、参数、返回值。C语言中的函数有自己特定的类型。

C语言中通过typedef为函数类型重命名:

  1. typedef int f(int, int); // f 为函数类型
  2. typedef void p(int); // p 为函数类型

这一点和数组一样,因此我们可以用一个指针变量来存放这个入口地址,然后通过该指针变量调用函数。

  1. typedef int(p)(int, int);
  2. void my_func(int a,int b){
  3. printf("%d %d\n",a,b);
  4. }
  5. void test(){
  6. p p1;
  7. //p1(10,20); //错误,不能直接调用,只描述了函数类型,但是并没有定义函数体,没有函数体无法调用
  8. p* p2 = my_func;
  9. p2(10,20); //正确,指向有函数体的函数入口地址
  10. }

1.2 函数指针(指向函数的指针)

  1. 函数指针定义方式(先定义函数类型,根据类型定义指针变量);
  2. 先定义函数指针类型,根据类型定义指针变量;
  3. 直接定义函数指针变量; ```c int my_func(int a,int b){ printf(“ret:%d\n”, a + b); return 0; }

//1. 先定义函数类型,通过类型定义指针 void test01(){ typedef int(FUNC_TYPE)(int, int); FUNC_TYPE f = my_func; //如何调用? (f)(10, 20); f(10, 20); }

//2. 定义函数指针类型 void test02(){ typedef int(FUNC_POINTER)(int, int); FUNC_POINTER f = my_func; //如何调用? (f)(10, 20); f(10, 20); }

/3. 直接定义函数指针变量 void test03(){

  1. int(*f)(int, int) = my_func;
  2. //如何调用?
  3. (*f)(10, 20);
  4. f(10, 20);

}

  1. **函数指针数组:**<br />**int * (*fun[5])(int *p,int *p2);**<br />**函数指针数组指针**<br />**int * (*(fun)[5])(int *p,int *p2);**
  2. <a name="mBmdD"></a>
  3. ### 1.3 函数指针数组
  4. 函数指针数组,每个元素都是函数指针。
  5. ```c
  6. void func01(int a){
  7. printf("func01:%d\n",a);
  8. }
  9. void func02(int a){
  10. printf("func02:%d\n", a);
  11. }
  12. void func03(int a){
  13. printf("func03:%d\n", a);
  14. }
  15. void test(){
  16. #if 0
  17. //定义函数指针
  18. void(*func_array[])(int) = { func01, func02, func03 };
  19. #else
  20. void(*func_array[3])(int);
  21. func_array[0] = func01;
  22. func_array[1] = func02;
  23. func_array[2] = func03;
  24. #endif
  25. for (int i = 0; i < 3; i ++){
  26. func_array[i](10 + i);
  27. (*func_array[i])(10 + i);
  28. }
  29. }

1.4 函数指针做函数参数(回调函数)

函数参数除了是普通变量,还可以是函数指针变量。

  1. //形参为普通变量
  2. void fun( int x ){}
  3. //形参为函数指针变量
  4. void fun( int(*p)(int a) ){}

函数指针变量常见的用途之一是把指针作为参数传递到其他函数,指向函数的指针也可以作为参数,以实现函数地址的传递。

  1. int plus(int a, int b)
  2. {
  3. return a + b;
  4. }
  5. int sub(int a, int b)
  6. {
  7. return a - b;
  8. }
  9. int mul(int a, int b)
  10. {
  11. return a * b;
  12. }
  13. int division(int a, int b)
  14. {
  15. return a / b;
  16. }
  17. //函数指针 做函数的参数 --- 回调函数
  18. void Calculator(int(*myCalculate)(int, int), int a, int b)
  19. {
  20. int ret = myCalculate(a, b); //dowork中不确定用户选择的内容,由后期来指定运算规则
  21. printf("ret = %d\n", ret);
  22. }
  23. void test01()
  24. {
  25. printf("请输入操作符\n");
  26. printf("1、+ \n");
  27. printf("2、- \n");
  28. printf("3、* \n");
  29. printf("4、/ \n");
  30. int select = -1;
  31. scanf("%d", &select);
  32. int num1 = 0;
  33. printf("请输入第一个操作数:\n");
  34. scanf("%d", &num1);
  35. int num2 = 0;
  36. printf("请输入第二个操作数:\n");
  37. scanf("%d", &num2);
  38. switch (select)
  39. {
  40. case 1:
  41. Calculator(plus, num1, num2);
  42. break;
  43. case 2:
  44. Calculator(sub, num1, num2);
  45. break;
  46. case 3:
  47. Calculator(mul, num1, num2);
  48. break;
  49. case 4:
  50. Calculator(division, num1, num2);
  51. break;
  52. default:
  53. break;
  54. }
  55. }

注意:函数指针和指针函数的区别