函数指针和指针函数
a)int *pfun(int, int);
b)int (*pfun)(int, int);
a)中由于*的优先级低于“()”的优先级,因而pfun首先和后面的()结合即pfunc(int,int),也就意味着,pfun是一个函数。即:
int *(pfun(int, int));
接着再和前面的“*”结合,说明这个函数的返回值是一个指针。由于前面还有一个int,也就是说,pfun是一个返回值为整型指针的函数。
b)通过括号强行将pfun首先与“*”结合,也就意味着,pfun是一个指针,接着与后面的“()”结合,说明该指针指向的是一个函数,然后再与前面的int结合,也就是说,该函数的返回值是int。由此可见,pfun是一个指向返回值为int的函数的指针。
函数指针:它是指向函数的指针变量,因而“函数指针”本身首先是一个指针变量,只不过该指针变量指向函数。每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,可用该指针变量调用函数。
函数指针有两个用途:
- 调用函数
- 做另一个函数的参数
函数指针的声明方法:
函数类型 (标志符 指针变量名)(形参列表);
- 函数类型说明函数的返回类型;
- “(标志符 指针变量名) ”中的括号不能省略,若省略整体则成为一个函数说明,说明了一个返回的数据类型是指针的函数;
- 形参列表:表示指针变量指向的函数所带的参数列表;
例子:
1 int (*f)(int x);
2 int (*ptr)(double x);
函数名和数组名一样代表了函数代码的首地址,因此在赋值时,直接将函数指针指向函数名称
1 int func( int x ); /* 声明了一个函数 */ 2 int (*f)(int x); /* 声明子一个函数指针 */ 3 f = func; /* 将func函数的首地址赋给指针 */
由于函数名func代表了函数的首地址,因此经过上述赋值以后,指针f指向函数func(x)的代码的首地址。
可以通过函数指针调用函数。
例子:
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 /** 5 *比较两个int类型的整数大小,返回较大的。 6 */ 7 int max( int x, int y ); /* 函数声明 */ 8 int main() 9 { 10 int x = 5; 11 int y = 6; 12 int result1, result2; /* 存储函数返回值 */ 13 14 /** 15 *函数指针的声明, 注意函数指针中的形参列表与要指向的函数的形参列表 16 *完全一致(包括形参类型和形参个数) 17 */ 18 int (*func)(int, int); 19 20 func = max; /* 给函数指针func赋值,使它指向函数max */ 21 22 /* 通过函数指针调用函数max */ 23 result1 =(*func)(x,y); 24 25 /*以下这种调用方式也可以*/ 26 result2 = func(x,y); 27 printf("result1 = %d\nresult2 = %d\n", result1, result2); 28 return 0; 29 } 30 31 int max( int x, int y ) /* 函数定义 */ 32 { 33 int z; 34 z = x > y ? x : y; 35 return z; 36 }
这个简单的例子体现了函数指针用来调用函数的功能。
下面这个例子体现了函数指针作为另一个函数的参数:
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 /** 5 *max函数:比较两个int类型的整数大小,返回较大的。 6 *min函数:比较两个int类型的整数大小,返回较小的 7 */ 8 int max( int x, int y ); /* 函数声明 */ 9 int min( int x, int y ); 10 11 /** 12 *func函数中 int (*p)(int, int)是一个函数指针,该函数功能: 13 *把max函数名赋给函数指针p时,求出的是两个整数中的较大值 14 *把min函数名赋给函数指针p时,求出的是两个整数中的较小值 15 */ 16 int func( int (*p)(int, int), int x, int y ); 17 18 int main() 19 { 20 int x = 1; 21 int y = 6; 22 int resultMin, resultMax; /* 存储函数返回值 */ 23 24 resultMax = func(max, x,y); 25 printf("resultMax = %d\n", resultMax); 26 27 resultMin = func(min, x, y); 28 printf("resultMin = %d\n", resultMin ); 29 } 30 31 int max( int x, int y ) /* 函数定义 */ 32 { 33 int z; 34 z = x > y ? x : y; 35 return z; 36 } 37 38 int min( int x, int y ) 39 { 40 int z; 41 z = x < y ? x : y; 42 return z; 43 } 44 45 int func( int (*p)(int,int), int x, int y ) 46 { 47 return ((*p)(x,y)); 48 } 49 50 /*运行结果: 51 resultMax = 6 52 resultMin = 1 53 */
当然,在程序的第45行中,int func( int (*p)(int, int), int x, int y );中,第一个参数也可以使用typedef来简化:
修改如下:
typedef int (*func_ptr)(int, int);
func_ptr p;
int func( func_ptr p, int x, int y );
将上面那个程序修改如下:
- main()函数不变动
- max()和min()函数不变动
- func()函数变动并在main函数外声明函数指针具体如下:
typedef int (*func_ptr)(int, int); //以后可以当作类型来定义一个变量如: func_ptr p; //int func( int (*p)(int, int), int x, int y ); int func( func_ptr p, int x, int y );
1 int func( func_ptr p, int x, int y ) 2 { 3 return (p(x,y)); 4 }
函数指针在事件驱动型的程序中应用颇多,特别是用来设置回调函数。
浙公网安备 33010602011771号