1.一般定义形式:返回值的数据类型(*指针变量名)();for example: int function(int a, int b){...;}int (*pointer_of_function)();pointer_of_function = function; //相关联的语句就是这么简单。
2.函数的调用可以通过函数名调用,也可以通过函数指针调用(即用指向函数的指针变量调用)。
3.(*p)() 表示定义一个指向函数的指针变量,它不是固定指向哪一个函数的,而只是表示定义了这样一个类型的变量,它是专门用来存放函数的入口地址的。
在程序中把哪一个函数的地址赋给它,它就指向哪一个函数。
在一个程序中,一个指针变量可以先后指向返回类型相同的不同的函数。
4.在给函数指针变量赋值时,只需给出函数名而不必给出参数,如:pointer_of_function = function ,因为是将函数入口地址赋给pointer_of_function, 而不牵涉到实参与形参结合的问题。
不能写成pointer_of_function = function(a,b)。
5.用函数指针变量调用函数时,只需将(*P)代替函数名即可,在(*p)之后的括弧中根据需要写上实参。
6.对指向函数的指针变量,像p++ 等类似运算是没有意义的。
7.区别int (*p)() 与int *p():由于()的优先级高于*,它就成了声明一个函数了,这个函数的返回值是指向整形变量的指针。
1 定义和调用程序在编译后,每个函数都有一个首地址(也就是函数第一条指令的地址),这个地址称为函数的指针。
可以定义指向函数的指针变量,使用指针变量间接调用函数。
下面通过一个简单的例子来说明:float max(float x,float y){return x>y?x:y;}float min(float x,float y){return x<y?x:y;}main(){float a=1,b=2, c;float (*p)(float x, float y);p=max;c=(*p)(a,b); /*等效于max(a,b)*/printf("\nmax=%f",c);p=min;c=(*p)(a,b); /*等效于min(a,b)*/printf("\nmin=%f",c);}程序运行的结果为:max=2.000000min=1.000000说明:(1)语句float (*p)(float x, float y);定义了一个指向函数的指针变量。
函数的格式是:返回值为float型,形式参数列表是(float x, float y)。
p定义后,可以指向任何满足该格式的函数。
(2)定义指向函数的指针变量的格式为:(3)数据类型(*指针变量名称)(形式参数列表);(4)其中数据类型是函数返回值的类型,形式参数列表是函数的形式参数列表。
(5)形式参数列表中,参数名称可以省略。
比如,float (*p)(float x, float y);可以写为:(6)float (*p)(float, float);(7)注意指针变量名称两边的括号不能省略。
(8)语句p=max;将max函数的首地址值赋给指针变量p,也就是使p指向函数max。
C语言中,函数名称代表函数的首地址。
(9)第一个c=(*p)(a,b);语句:由于p指向了max函数的首地址,(*p)(a,b)完全等效于max(a,b)。
函数返回2.0。
注意*p两边的括号不能省略。
(10)语句p=min; 将min函数的首地址值赋给指针变量p。
p是一个变量,p的值实际上是一个内存地址值,可以指向max,也可以指向min,但指向函数的格式必须与p的定义相符合。
(11)第二个c=(*p)(a,b);语句:由于p指向了min函数的首地址,(*p)(a,b)完全等效于min(a,b)。
函数返回1.0。
(12)将函数首地址赋给指针变量时,直接写函数名称即可,不用写括号和函数参数。
(13)利用指针变量调用函数时,要写明函数的实际参数。
提示:定义一个指向函数的指针变量时,一定要使用括号。
比较下面的两个定义:float (*p1)(int x, long y);float *p2(int x, long y);第一个语句定义了一个指向函数的指针变量p1;第二个语句声明了一个函数p2,p2的形式参数为(int x, long y),返回值为一个float型的指针。
2 指向函数的指针作为函数参数有时候,许多函数功能不同,但它们的返回值和形式参数列表都相同。
这种情况下,可以构造一个通用的函数,把函数的指针作为函数参数,这样有利于进行程序的模块化设计。
比如下面的例子中,我们把对2个float型数进行加、减、乘、除操作的4个函数归纳成一个数学操作函数MathFunc。
这样,在调用MathFunc函数时,只要将具体函数名称作为函数实际参数,MathFunc就会自动调用相应的加、减、乘、除函数,并计算出结果。
下面是程序的代码:float Plus(float f1, float f2);float Minus(float f1, float f2);float Multiply(float f1, float f2);float Divide(float f1, float f2);float MathFunc(float (*p)(float, float), float para1,float para2);main(){float a=1.5, b=2.5;printf("\na+b=%f", MathFunc(Plus, a,b));printf("\na-b=%f", MathFunc(Minus, a,b));printf("\na*b=%f", MathFunc(Multiply, a,b));printf("\na/b=%f", MathFunc(Divide, a,b));}float Plus(float f1, float f2){return f1+f2;}float Minus(float f1, float f2){return f1-f2;}float Multiply(float f1, float f2){return f1*f2;}float Divide(float f1, float f2){return f1/f2;}floatMathFunc(float (*p)(float, float), float para1,float para2){return (*p)( para1, para2);}程序运行的结果为:a+b=4.000000a-b=-1.000000a*b=3.750000a/b=0.600000例8-10 利用指向函数的指针,求如下函数在一个区段内的最小值。
本题可以利用指向函数的指针。
虽然所给的函数互不相同,但其在一定区间内求最小值的算法都是通用的。
因此,可以写一个通用的函数float GetMin(float (*p)(float), float fPos1,float fPos2),用于计算不同函数的最小值。
该函数的第一个参数p是一个指向函数的指针,p指向包含一个float型参数的函数。
对应于题目的要求,分别写三个数学函数。
在主函数中,调用GetMin时,第一个参数分别使用上述数学函数的名称,后两个参数传入区间值。
这样,调用三次GetMin即可以求出三个函数在给定区间的最小值。
#include "math.h"float f1(float x){return x*x+2*x+1; /*f1的表达式*/}float f2(float x){return 2*sin(x); /*f2的表达式*/}float f3(float x){return 2*x+1; /*f3的表达式*/}/*p为指向函数的指针,fPos1和fPos2为左右区间的值*/float GetMin(float (*p)(float), float fPos1,float fPos2){float f,t, fMin, fStep=0.01; /* fStep为步长值*//*在fPos1至fPos2的区间内,以fStep为步长,依次比较最小f值*/fMin=(*p)(fPos1);for(f=fPos1;f<=fPos2;f+=fStep){t=(*p)(f);if(t<fMin)fMin=t;}/*返回求出的最小值*/return fMin;}main(){/*直接计算并输出结果*/printf("\nMin value of f1: %f",GetMin(f1,-1,1));printf("\nMin value of f2: %f",GetMin(f2,1,3));printf("\nMin value of f3: %f",GetMin(f3,-1,1));}程序运行的结果为:Min value of f1: 0.000000Min value of f2: 0.282244Min value of f3: -1.000000主函数main调用GetMin函数时,传入了函数名称和区间值。
GetMin函数在计算函数最小值时,根据传入的函数指针p调用相应的函数。
灵活使用指向函数的指针可以提高程序的扩充性。
比如本题,如果要增加条件,计算一个f4(x)=2*logx+1在(0,5)内的最小值,那么我们只需要增加一个f4函数的定义,然后在main 函数中就可以直接进行计算GetMin(f4,0,5),GetMin函数不用进行任何修改。