1 函数指针
1.1 函数类型
通过什么来区分两个不同的函数?
一个函数在编译时被分配一个入口地址,这个地址就称为函数的指针,函数名代表函数的入口地址。
函数三要素: 名称、参数、返回值。C语言中的函数有自己特定的类型。
C语言中通过typedef为函数类型重命名:
typedef int f(int, int); // f 为函数类型typedef void p(int); // p 为函数类型
这一点和数组一样,因此我们可以用一个指针变量来存放这个入口地址,然后通过该指针变量调用函数。
typedef int(p)(int, int);void my_func(int a,int b){printf("%d %d\n",a,b);}void test(){p p1;//p1(10,20); //错误,不能直接调用,只描述了函数类型,但是并没有定义函数体,没有函数体无法调用p* p2 = my_func;p2(10,20); //正确,指向有函数体的函数入口地址}
1.2 函数指针(指向函数的指针)
- 函数指针定义方式(先定义函数类型,根据类型定义指针变量);
- 先定义函数指针类型,根据类型定义指针变量;
- 直接定义函数指针变量; ```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(){
int(*f)(int, int) = my_func;//如何调用?(*f)(10, 20);f(10, 20);
}
**函数指针数组:**<br />**int * (*fun[5])(int *p,int *p2);**<br />**函数指针数组指针**<br />**int * (*(fun)[5])(int *p,int *p2);**<a name="mBmdD"></a>### 1.3 函数指针数组函数指针数组,每个元素都是函数指针。```cvoid func01(int a){printf("func01:%d\n",a);}void func02(int a){printf("func02:%d\n", a);}void func03(int a){printf("func03:%d\n", a);}void test(){#if 0//定义函数指针void(*func_array[])(int) = { func01, func02, func03 };#elsevoid(*func_array[3])(int);func_array[0] = func01;func_array[1] = func02;func_array[2] = func03;#endiffor (int i = 0; i < 3; i ++){func_array[i](10 + i);(*func_array[i])(10 + i);}}
1.4 函数指针做函数参数(回调函数)
函数参数除了是普通变量,还可以是函数指针变量。
//形参为普通变量void fun( int x ){}//形参为函数指针变量void fun( int(*p)(int a) ){}
函数指针变量常见的用途之一是把指针作为参数传递到其他函数,指向函数的指针也可以作为参数,以实现函数地址的传递。
int plus(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 division(int a, int b){return a / b;}//函数指针 做函数的参数 --- 回调函数void Calculator(int(*myCalculate)(int, int), int a, int b){int ret = myCalculate(a, b); //dowork中不确定用户选择的内容,由后期来指定运算规则printf("ret = %d\n", ret);}void test01(){printf("请输入操作符\n");printf("1、+ \n");printf("2、- \n");printf("3、* \n");printf("4、/ \n");int select = -1;scanf("%d", &select);int num1 = 0;printf("请输入第一个操作数:\n");scanf("%d", &num1);int num2 = 0;printf("请输入第二个操作数:\n");scanf("%d", &num2);switch (select){case 1:Calculator(plus, num1, num2);break;case 2:Calculator(sub, num1, num2);break;case 3:Calculator(mul, num1, num2);break;case 4:Calculator(division, num1, num2);break;default:break;}}
注意:函数指针和指针函数的区别
