可以用指针变量指向整型变量、字符串、数组,也可以指向一个函数。一个函数在编译时被分配给一个入口地址。这个入口地址就称为函数的指针。可以用一个指针变量指向函数,然后通过该指针变量调用此函数。先通过一个简单的例子来回顾一下函数的调用情况。例 求a和b中的大者。先列出按一般方法的程序。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)代替函数名即可(p为指针变量名),在(*p)之后的括弧中根据需要写上实参。如下面语句表示:“调用由p指向的函数,实参为 a,b。得到的函数值赋给c。” c=(*p)(a,b);注意函数的返回值是什么类型?从上例对指针变量p的定义可以知道,函数的返回值是整型的,因此将其值赋给整型变量c是合法的。 (6) 对指向函数的指针变量,像p+n、p++、p--等运算是无意义的。

评论