本文来全面的学习一下函数指针。在概念上,函数指针不难理解,和指向变量的指针一样,指向着一个地址,这个地址是一个函数的入口地址(本质上函数名就是函数的入口地址)。在形式上,由于函数原型比变量的形式要复杂,所以函数指针的使用形式要复杂一些。不要因为指针前面加的是函数二字觉得神秘,把“函数”看作是“函数变量”即可。
指针函数的什么?:
先来说下另一个概念,叫指针函数,个人感觉这个叫法其实是有点勉强的,似乎是为了像指针数组、数组指针一样做对应。指针函数是一个返回值是指针类型的函数。因此指针二字体现的是返回值的属性。它的形式形如
int *f(int x,int y);
指针符号会优先和数据类型结合,形成int*类型的返回值。那么在函数内部记得返回一个int*类型的变量,注意,这个指针返回值不要指向函数内部的局部变量,由于返回之后局部变量被销毁,指针的值就错误了。
函数指针的形式:
继续回到函数指针。对比上面的,函数指针的形式形如,
int (*f)(int x, int y);
为了让指针符号和函数名结合,必须要加括号。
函数指针的用法:
普通的指针是要指向它声明时定义的类型的变量,而函数指针则要指向它声明时定义的形式的函数。上面举例的f,可以指向任何形如这样“有两个int参数且返回int”的函数。
1、声明函数指针:像声明普通指针一样,int (*f)(int x, int y);,一般是把fun替换成(*f)。
2、给函数指针赋值:像赋值普通指针一样,加入有一个函数int fun(int a, int b);,那么可以让f指向这个函数,f=fun;
3、使用函数指针:用它来做什么呢?函数是做什么的那函数指针就是做什么的。当我想调用函数fun的时候,用函数指针f来调用,如int a = f(3, 5)。
#include <stdio.h>
int fun(int a, int b)
{
return a + b;
}
void main()
{
int (*f)(int, int);
f = fun;
int a = f(3,5);
printf("%d\n",a);
}
函数指针终归是一个变量,是一个存储函数入口地址的变量。那么它是可以作函数参数和返回值的。
1、函数指针给别的函数作参数的时候,和普通的指针作参数在形式上区别不大,一样是按顺序写在参数的位置上。
2、函数指针给别的函数作返回值,则在形式上看起来比较复杂。
函数指针作为函数返回值:
其意义是,一个函数A的返回值类型是一个函数指针(指向形如B的函数的指针)。
下面举例说明:
函数 int B(int , int );
函数指针int (*f)(int, int);
f = B;那么函数指针f指向了函数B。
函数 int (*A(int))(int, int),其中A(int)是函数A的名称和参数,外面的部分是A的返回值。
注意这里的形式:A(int)是A函数的主体部分,指针符号*并不是和A结合的(*A不可以括在一起),也不是和第一个int结合的(第一个int和*之间要有括号),而是和那个没有名称代号的返回值结合的。
下面代码例子中函数A其作用是:若输入参数是1,那么返回一个做加法运算的函数的指针;若输入参数不是1,那么返回一个做减法运算的函数的指针。
#include <stdio.h>
int B(int x, int y)
{
return x + y;
}
int C(int x, int y)
{
return x - y;
}
int (*A(int m))(int x, int y) //注意形式!
{
int (*f)(int, int);//注意形式!
if(m == 1)
f = B;
else
f = C;
return f;
}
void main()
{
int (*k)(int, int);
int in;
scanf("%d",&in);
k = A(in);
int out = k(10,7);
printf("%d\n",out);
}
函数指针的难点在于函数指针的定义形式和函数指针作为返回值时的定义形式。
最后看一道题:定义一个函数指针,指向的函数有两个int形参并且返回一个函数指针,返回的指针指向一个有一个int形参且返回int的函数?
解答:
1、先写有两个int形参的函数fun: fun(int, int)
2、给fun加上函数指针类型的返回值: int (*fun(int, int))(int)
3、定义指向形如函数fun的函数指针f:把fun替换成(*f),int (*(*f)(int, int))(int)
下面代码是把上面的代码添加了针对这道题的情况:
#include <stdio.h>
int B(int x, int y)
{
return x + y;
}
int C(int x, int y)
{
return x - y;
}
int (*A(int m))(int x, int y) //注意形式!
{
int (*f)(int, int);//注意形式!
if(m == 1)
f = B;
else
f = C;
return f;
}
void main()
{
int (*k)(int, int);
int in;
scanf("%d",&in);
int (*(*Y)(int m))(int x, int y);//注意形式!
Y = A;
k = Y(in);
int out = k(10,7);
printf("%d\n",out);
}