论文导读:当在程序中定义变量时,编译系统就会为变量分配相应的存储单元,由此就形成了地址的概念。数据在内存中是存放在某一地址上的,代码同样也是存储在内存中的某一地址上,因此指针即可向内存中存储的数据也可以指向程序中的代码,这就是函数指针。而指针函数则是指返回值是一个指针的函数。
关键词:函数指针,指针函数,地址
1.引言
一个程序由两部分组成:代码部分和数据部分。当在程序中定义变量时,编译系统就会为变量分配相应的存储单元,由此就形成了地址的概念。数据在内存中是存放在某一地址上的,代码同样也是存储在内存中的某一地址上,因此指针即可向内存中存储的数据也可以指向程序中的代码,这就是函数指针。而指针函数则是指返回值是一个指针的函数。
2.函数指针
可以用指针变量指向整型变量、字符串、数组,也可以指向一个函数。在C语言中规定,一个函数总是占用一段连续的内存区,而函数名就是该函数所占内存区的首地址。我们可以把函数的这个首地址(或称入口地址)赋给一个指针变量,使该指针变量指向该函数。然后通过指针变量就可以找到并调用这个函数。论文参考网。我们把这种指向函数的指针变量称为“函数指针变量”。
函数指针变量定义的一般形式为:
类型说明符(*函数指针变量名)(形式参数表);
例如: int(*pf)( );
表示pf是一个指向函数入口地址的指针变量,该函数的返回值(函数值)是整型。
下面通过例子来说明用函数指针形式实现对函数调用的方法。在我们没有学习指针变量之前,我们调用函数时是通过函数名来完成的。
2.1用函数名实现函数的调用
源程序代码如下:
#include<stdio.h>
int max(inta,int b)
{if(a>b)return a;
elsereturn b;}
void main()
{ int max(inta,int b);
int a,b,c;
printf('inputtwo numbers:');
scanf('%d,%d',&a,&b);
c=max(a,b);/*用函数名调用*/
printf('max=%d ',c);
}
程序运行结果如下:

2.2用函数指针来实现函数的调用
源程序代码:
int max(inta,int b)
{if(a>b) returna;
else return b;}
void main()
{ int max(inta,int b);
int (*pmax)(int ,int ); /*定义了一个指向整型函数的指针*/
int a,b,c;
pmax=max;/*使函数指针指向该函数的入中地址*/
printf('inputtwo numbers:');
scanf('%d,%d',&a,&b);
c=(*pmax)(a,b);/*通过指针调用max函数*/
printf('max=%d ',c);}
程序运行结果如下:

实例说明:
 (1) 本实例中“int (*pmax)( int ,int );”用来定义pmax是一个指向函数的指针,该函数有两个整型参数,函数值为整型。
(2) 赋值语句“pmax=max;”的作用是将函数max的入口
地赋给指针变量pmax(函数名代表该函数的入口地址)。
这时,pmax就是指向函数max的指针变量,此时pmax
和max都指向函数的开头,见右图。调用*pmax就是调
用max。
(3) 请注意:pmax是指向函数的指针变量,它只能指向函数
的入口处而不能指向函数中间的某一条指令处,因此不能
用 *(pmax+1)来表示函数的下一条指令。
(4) 在main函数中有一个赋值语句:
c=(*pmax)(a,b);与实例2.1中c=max(a,b);等价。这就是用指
针形式实现函数的调用。以上用两种方法实现函数的调用,结果是一样的。论文参考网。
2.3使用函数指针
问题:编写程序,根据用户的选择分别调用sin 、cos、 tan函数计算一个角度的三角函数值。角度值从键盘输入。
源程序代码如下:
#include<stdio.h>
#include<math.h>
main()
{double(*p[3])(double)={sin,cos,tan};
intchoice,angle;
printf('Pleaseinput angle=?');
scanf('%d',&angle);
printf('Pleaseinput choice(0-sin,1-cos,2-tan)=?');
scanf('%d',&choice);
printf('%lf ',(*p[choice])(angle*3.14159/180));
}
实例说明:
(1)在本实例中“double (*p[3])(double)={sin,cos,tan};”定义了一个具有3个元素的函数指针数组p,其中3个元素分别指向数学函数sin、cos、tan。
(2)当程序运行时给angle赋值30,给choice赋值0。则:
程序中“priintf('%lf ',(*p[choice])(angle*3.14159/180));”
转换为:
“printf('%lf ',(*p[0])(30*3.14159/180));”(与“printf('%lf ',sin(30*3.14159/180));”等价)。
程序运行结果如下:

3. 指针函数
一个函数可以返回一个整型值、字符值、实型值等,也可以返回指针型的数据,即地址。指针函数则是指返回值是一个指针的函数。在C语言中允许一个函数的返回值是一个指针(即地址),这种返回指针值的函数称为指针函数。论文参考网。
定义指针型函数的一般形式为:
类型说明符 *函数名(形参表)
{
…… /*函数体*/
}
如: int *pf(int x,int y)
{
...... /*函数体*/
}
pf是函数名,调用它以后能得到一个指向整型数据的指针(地址)。x、y是函数pf的形参,为整型。请注意在*pf 两侧没有括号,在pf的两侧分别为*运算符和()运算符。而()优先级高于*,因此pf先与()结合。显然这是一个函数形式。这个函数前面有一个*,表示此函数是指针型函数(函数值是指针)。最前面的int表示返回的指针指向整型变量。对C的这种定义形式,用时要十分小心。
例:有若干个学生的成绩(每个学生有4门课程),要求在用户输入学生序号后,能输出该学生的全部成绩。
源程序代码如下:
#include<stdio.h>
void main()
{floatscore[][4]={{60,70,80,90},{56,89,67,88},{34,78,90,66}};
float*search(float(*pointer)[4],int n);
float *p;
int i,m;
printf('inputthe number of student:');
scanf('%d',&m);
printf('Thescores of No.%d are: ',m);
p=search(score,m);
for(i=0;i<4;i++)
printf('%5.2f ',*(p+i));
printf(' ');
}
float*search(float(*pointer)[4],int n)
{float*pt;
pt=*(pointer+n);
return(pt);
}
程序运行结果如下:

4.结束语
特别注意的是函数指针和指针函数这两者在写法和意义上的区别。如int(*p)()和int *p()是两个完全不同的量。int(*p)()是一个变量说明,说明p 是一个指向函数入口的指针变量,该函数的返回值是整型量,(*p)的两边的括号不能少。int *p() 则不是变量说明而是函数说明,说明p是一个指针型函数,其返回值是一个指向整型量的指针,*p两边没有括号。作为函数说明, 在括号内最好写入形式参数,这样便于与变量说明区别。 对于指针函数定义,int *p()只是函数头部分,一般还应该有函数体部分,这样才能构成一个完整的函数结构。
参考文献:
[1] 陈强.C语言核心开发技术从入门到精通[M].北京:电子工业出版社,2009.
[2] 匡松.C语言程序设计[M] .北京:中国铁道出版社,2008.
[3] 李俊杰.C语言复习指南与题解[M] .北京:清华大学出版社,2003.
[4] 谭浩强.C程序设计[M] .北京:清华大学出版社,2005.
|