1用函数指针变量调用函数
可以用指针变量指向整形变量、字符串、数组,也可以指向一个函数。一个函数在编译时被分配给一个入口地址。这个入口地址就称为函数的指针。可以用一个指针变量指向函数,然后通过该指针变量调用此函数。
(1)函数调用的情况
例子1
main()
{
int max(int,int);
int a,b,c;
scanf("%d,%d",&a,&b);
c=max(a,b);
printf("a=%d,b=%d,max=%d",a,b,c);
}
max(int x,int y)
{
int z;
if(x>y)z=x;
else z=y;
return(z);
}
main函数中的"c=max(a,b);"包含了一次函数调用(调用max函数)。每一个函数都占用一段内存单元,它们有一个起始地址。因此,可以用一个指针变量指向一个函数,通过指针变量来访问它指向的函数。
将main函数改写为
main()
{
int max(int,int);
int(*p)();
int a,b,c;
p=max;
scanf("%d,%d",&a,&b);
c=(*p)(a,b);
printf("a=%d,b=%d,max=%d",a,b,c);
}
其中"int (*p)();"定义p是一个指向函数的指针变量,此函数带回整型的返回值。注意*p两侧的括号不可省略,表示p先与*结合,是指针变量,然后再与后面的()结合,表示此指针变量指向函数,这个函数值(即函数返回的值)是整型的。如果写成"int *p();",则由于()优先级高于*,它就是声明一个函数了(这个函数的返回值是指向整型变量的指针)。
赋值语句"p=max;"的作用是将函数max的入口地址赋给指针变量p。和数组名代表数组起始地址一样,函数名代表函数的入口地址。这时,p就是指向函数max的指针变量,也就是p和max都指向函数的开头,调用*p就是调用函数max。请注意p是指向函数的指针变量,他只能指向函数的入口处,而不能指向函数中间的某一条指令处,因此不能用*(p+1)表示函数的下一条指令。
在main函数中有一个赋值语句 c=(*p)(a,b);它包含函数的调用,和"c=max(a,b);"等价。这就是用指针形式实现函数的调用。以上两种方法实现函数的调用,实现的结果是一样的。
说明:
(1)指向函数的指针变量的一般实现形式为
数据类型 (*指针变量名)();
这里的“数据类型”是指函数返回值的类型。
(2)函数的调用可以通过函数名调用,也可以通过函数指针调用(即用指向函数的指针变量调用)。
(3)(*p)()表示定义一个指向函数的指针变量,它不是固定指向哪一个函数的而只是表示定义了这样一个类型的变量,它是专门用来存放函数的入口地址的。在程序中把哪个函数的地址赋给它,它就指向哪一个函数。在一个程序中,一个指针变量可以先后指向类型相同的不同函数。
(4)在给函数指针变量赋值时,只需给出函数名而不必给出参数,如:
p=max;
因为是将函数入口地址赋给p,而不牵涉到实参和形参结合问题。不能写成“p=max(a,b);"形式。
(5)用函数指针变量调用函数时,只需将(*p)代替函数名即可。
(6)对指向函数的指针变量,像p+n、p++等运算是无意义的。