如何定义一个指向任何函数的指针
(一)用函数指针变量调用函数 可以用指针变量指向整形变量、字符串、数组、结构体、也可以指向一个函数。一个函数在编译时被分配一个入口地址。这个入口地址就称为函数指针。可以用一个指针变量指向函数,然后通过该指针变量调用此函数。用简单的数值比较为例:1#include2#include34intmain()5{6intmax(int,int);7int(*p)(int,int);8inta,b,c;9p=max;10scanf("%d,%d",&a,&b);11c=(*p)(a,b);12printf("a=%d,b=%d,max=%d
",a,b,c);13return0;14}1516intmax(intx,inty)17{18intz;19if(x>y)z=x;20elsez=y;21return(z);22} main函数中的"c=max(a,b);"包括了一次函数的调用。每一个函数都占用一段内存单元。因此,可以用一个指针变量指向一个函数,通过指针变量来访问它指向的函数。 第7行:int(*p)(int,int);用来定义p是一个指向函数的指针变量,该函数有两个整形参数,函数值为整形。注意*p两侧的括号不可省略,表示p先与*结合,是指针变量,然后再与后面的()结合,表示此指针变量指向函数,这个函数值(即函数的返回值)是整形的。如果写成int*p(int,int),由于()的优先级高于*,它就成了声明一个函数P(这个函数的返回值是指向整形变量的指针)。 赋值语句p=max;作用是将函数max的入口地址赋给指针变量p。和数组名代表数组首元素地址类似,函数名代表该函数的入口地址。这时p就是指向函数max的指针变量,此时p和max都指向函数开头,调用*p就是调用max函数。但是p作为指向函数的指针变量,它只能指向函数入口处而不可能指向函数中间的某一处指令处,因此不能用*(p+1)来表示指向下一条指令。 注意: (1)指向函数的指针变量的一般定义形式为: 数据类型(*指针变量名)(函数参数列表) 这里数据类型就是函数返回值的类型 (2)int(*p)(int,int);它只是定义一个指向函数的指针变量p,它不是固定指向哪一个函数的,而只是表示定义这样一个类型的变量,它是专门用来存放函数的入口地址的。在程序中把哪一函数(该函数的值应该是整形的,且有两个整形参数)的地址赋给它,他就指向哪一个函数。在一个函数中,一个函数指针变量可以先后指向同类型的不同函数。 (3)p=max;在给函数指针变量赋值时,只需给出函数名而不必给出函数参数,因为是将函数的入口地址赋给p,而不涉及实参和形参的结合问题,不能写成p=max(a,b); (4)c=(*p)(a,b)在函数调用时,只需将(*p)代替函数名即可,后面实参依旧。 (5)对于指向函数的指针变量,像p++,p+n.....是无意义的。 (二)用指向函数的指针作为函数参数 函数指针变量通常的用途之一就是把指针作为参数传递到其他函数。 函数的参数可以是变量、指向变量的指针变量、数组名、指向数组的指针变量,也可以是指向函数的指针也可以作为参数,以实现函数地址的传递,这样就能够在被调用的函数中使用实参函数。 voidsub(int(*x1)(int),int(*x2)(int,int)){ inta,b,i,j; a=(*x1)(i); /*调用f1函数*/ b=(*x2)(i)(j);/*调用f2函数*/} 如果实参为两个函数名f1和f2.在函数首部定义x1、x2为函数指针变量,x1指向的函数有一个整形形参,x2指向的函数有两个形参。i和j是函数f1和f2所要的参数。函数sub的形参x1、x2(指针变量)在函数sub未被调用时并不占用内存单元,也不指向任何函数。在sub被调用时,把实参函数f1和f2的入口地址传给形式指针变量x1和x2. 既然在sub函数中要调用f1和f2函数,为什么不直接调用f1和f2而要用函数指针变量呢?确实,如果只是用到f1和f2函数,完全可以在sub函数中直接调用f1和f2,而不必设指针变量x1和x2。但是,如果在每次调用sub时,调用的函数不是固定的,下次是f3和f4,再是f5和f6...这时用指针变量就比较方便了。