函数作为C语言程序中一个重要的部分,在内存中也是有其地址的,也就是说函数也有自己的指针。
函数指针的一般定义格式为:
类型名 (*变量名)(参数类型表);
其中类型名就是指函数返回值的类型,变量名就是该函数指针的名称,例如:
int (*padd)(int,int);
定义了一个函数指针padd,它可以指向有两个整型参数并且返回值类型为整型的函数。
既然定义了函数指针,那么怎么通过函数指针调用函数呢?同样作为一个指针在使用之前我们要对其进行赋值。赋值时,将一个函数名赋给函数指针,但该函数必须已经定义或者说明,且该函数的返回值类型和函数指针的类型要一致。
假设函数add(i,j)已经定义,它有两个整型参数且返回一个整型变量,则:
padd=add;
这样将函数add()的入口地址赋给padd,padd就指向了add();
这样在调用函数时就用了两种方法:直接通过函数名调用或者通过指向函数的指针来实现对函数的调用。例如:
add(1,2);
或者
(*padd)(1,2);
可见通过函数指针调用函数的一般格式为:
(*函数指针名)(参数表)
当然,函数指针名前的*可以省略。
对于函数指针,我们在VC6.0环境下进行实验,代码如下:
#include<stdio.h>
int add(int a,int b);//定义函数add
void main()
{
int i=10;
int j=12;
int (*padd)()=add;//将函数add的地址赋给函数pFun
printf("%d\n",add(i,j));//调用函数add,不用*,说明*可以省略
printf("%d\n",(*add)(i,j));//调用函数add,用*,*和函数名用括号括起来
printf("%d\n",padd(i,j));//同add
printf("%d\n",(*padd)(i,j));
}
int add(int a ,int b)//定义函数
{
return (a+b);
}
实验结果:
22
22
22
22
同时由上述代码中我们可以发现,padd在定义时没有写入口参数,而在调用时却有两个形参,结果并没什么问题。另外,通过实验结果说明在通过函数的指针调用函数时,前面的*可以省略。
最后扯点题外话,函数名add和指向函数add的指针padd一样,他们都是函数指针,函数名也是指向函数的指针,那么这两者有什么区别呢?这两者的区别和指向数组的指针与数组名的关系一样,即:函数名add是一个指向函数add()的指针常量,而padd是一个指向函数add()的指针变量。
那么既然函数名本身就是指向函数的指针,那么我们在声明函数以及调用函数时,能否像指向函数的指针变量一样呢?
例如
int (*add)(int a,int b);
调用时:
(*add)(10,12);
为了验证其正确性,我们进行实验,代码如下:
#include<stdio.h>
int (*add)(int a,int b);
void main()
{
int result=(*add)(100,89);
printf("%d\n",result);
}
int (*add)(int a,int b)
{
return (a+b);
}
由上述代码可见,我们在定义函数时采用了定义函数指针的方式,当我们进行编译时系统提示错误,由此可见此种方法进行函数定义是不行的。
那么我们采用正常的定义函数的方式进行函数定义,然后调用时我们采用和通过函数指针调用函数一样的方式,代码如下:
#include<stdio.h>
int add(int a,int b);
void main()
{
int result=(*add)(100,89);
printf("%d\n",result);
}
int add(int a,int b)
{
return (a+b);
}
这时候代码运行结果正确,由此可见,我们可以通过也可以通过(*函数名)的方式来调用函数。