指针函数与函数的指针 指针函数 函数不但可以返回数值型数据而且还可以返回指针值,能够返回指针值的函数叫指针函数。 指针函数定义格式如下: 类型标识符 *函数名(形参表) 函数体 (1)定义指针函数时,函数名前必须有*。 (2)返回的是一个指针值,而不是一个数值型数据。 例 该函数是截去参数字符串的尾部空格,并以字符指针的形式返回该字符串。 1 #include <string.h> 2 #include <stdio.h> 3 char *trim(char *s) 4 { 5 char *p=s+strlen(s)-1; 6 while(p-s>=0&&*p==' ') 7 p--; 8 *(p+1)='/0'; 9 return s; 10 } 11 void main() 12 { 13 char str[]="china "; 14 char *cp=str; 15 printf("%s/n",trim(cp)); 16 } 注意,指针函数所返回的指针不能是函数返回后即不存在的对象,如函数中的自动变量,形参变量等。例如:下面的函数试图返回一个指向两个参数中较大者的指针: int * fun(int a,int b) { if(a>b) return &a; return &b; } 此函数不能得到预期的结果,其原因是,a和b都是形参变量,其生存期只延续到fun运行结束,因此调用fun所获得的结果是不可靠的。 函数指针 指针可以指向变量,可以指向数组也可以指向函数,指向函数的指针称为函数指针。 我们知道,程序在运算时,组成程序的函数是存储在内存的代码区中的,显然要找到执行的函数必须找到函数的入口地址,这个入口地址就叫做函数的指针。C语言函数名在程序运行时就指示了这个入口地址,也就是说函数名实质上也是地址,因此我们可以用一个指针变量来指向这个地址,即指向函数的入口地址。我们把这个指向函数入口地址的指针叫做函数指针,然后通过函数指针来调用指向的函数。 函数指针定义如下: 类型标识符 (*函数名)(形参表) 实际上指针变量名就相当于函数名了。 例 函数指针变量的使用 1 #include <stdio.h> 2 int max(int ,int); /*函数声明*/ 3 void main() 4 { 5 int (*pmax)(int ,int); /*定义函数指针变量*/ 6 int i=50,j=100; 7 pmax=max;//函数名代表函数入口地址,将入口地址送给函数指针 8 printf("%d/n",(*pmax)(i,j));//注意函数调用方式 9 } 10 int max(int x,int y) 11 { 12 return (x>y)?x:y; 13 } 关于函数指针变量的几点说明: (1)函数指针变量是有类型的,如上例中的第5行,函数指针变量能够接收的函数指针必须具有两个整型形参,而且返回值必须为整型。这样就相当于给定了函数的原型,以便进行严格的语法检查,另外此处只是定义函数指针变量,不是定义函数,因此不能有函数体。 (2)第7行pmax=max完成对函数指针变量的赋值,使用的函数指针来自于与pmax所需原型一致的函数max,赋值的方法是使用不带参数的函数名。 (3)第8行通过函数指针变量pmax调用了函数max,其中的(*pmax)相当于函数名max,该处也可以直接使用pmax函数指针变量作为函数名,调用形式也可以改为pmax(i,j)。 (4)一般指针的运算,如p+n、p++、p--等对函数指针不起作用。即函数指针不能用于计算。 (5)函数指针变量的优点是提供了一种将函数作为形参的机制。 例 设计一个函数process,可以完成对数进行多种处理 1 #include "stdio.h" 2 double process(double (* f)(double,double)) 3 { 4 int i; 5 double result=1; 6 for(i=2;i<=10;i++) 7 result=f(result,i); 8 return result; 9 } 10 int main() 11 { 12 double add(double,double); 13 double mul(double,double); 14 double rev(double,double); 15 printf("%.0f/n",process(add)); 16 printf("%.0f/n",process(mul)); 17 printf("%f/n",process(rev)); 18 return 0; 19 } 20 double add(double x,double y) 21 { 22 return x+y; 23 } 24 double mul(double x,double y) 25 { 26 return x*y; 27 } 28 double rev(double x,double y) 29 { 30 return x+1/y; 31 } 程序运行结果: 55 3628800 2.928968 |