浅谈函数指针

原创 2011年10月18日 11:43:17

 函数指针的概念,在潭浩强先生的C语言程序设计这本经典的教程中提及过,在大多数情况下我们使用不到,也忽略了它的存在。函数名实际上也是一种指针,指向函数的入口地址,但它又不同于普通的如int*、double*指针,看下面的例子来理解函数指针的概念:

int function( int x, int y );
int main ( void ) 
{
	int (*fun) ( int x, int y );
	int a = 10, b = 20;
	function( a, b );
	fun = function;
	(*fun)( a, b );
	......
}

第一行代码首先定义了一个函数function,其输入为两个整型数,返回也为一个整型数(输入参数和返回值可为其它任何数据类型);后面又定义了一个函数指针fun,与int*或double*定义指针不同的是,函数指针的定义必须同时指出输入参数,表明这是一个函数指针,并且*fun也必须用一对括号括起来;并将函数指针赋值为函数function,前提条件是*fun和function的输入参数和返回值必须保持一致,否则无法通过编译。可以直接调用函数function(),也可以直接调用函数指针,二者是等效的。

声明函数指针

    回调函数是一个程序员不能显式调用的函数;通过将回调函数的地址传给调用者从而实现调用。要实现回调,必须首先定义函数指针。尽管定义的语法有点不可思议,但如果你熟悉函数声明的一般方法,便会发现函数指针的声明与函数声明非常类似。请看下面的例子:

void f();    // 函数原型

上面的语句声明了一个函数,没有输入参数并返回void。那么函数指针的声明方法如下:

void (*) ();

函数存放在内存的代码区域内,它们同样有地址,我们如何能获得函数的地址呢?

如果我们有一个int test(int a)的函数,那么,它的地址就是函数的名字,这一点如同数组一样,数组的名字就是数组的起始地址。

定义一个指向函数的指针用如下的形式,以上面的test()为例:

int (*fp)(int a);     //这里就定义了一个指向函数的指针

函数指针绝对不能指向不同类型,或者是带不同形参的函数,在定义函数指针的时候我们很容易犯如下的错误。

int *fp(int a);      //这里是错误的,因为按照结合性和优先级来看就是先和()结合,然后变成了一个返回整形指针的函数了,而不是函数指针,这一点尤其需要注意!

例如函数原型为:

int  fun(int *, int);

则函数指针可以声明为:    int (*pf)(int *, int);
当然从上述例子看不出函数指针的优点,目的主要是想引出函数指针数组的概念。我们从上面例子可以得知,既然函数名可以通过函数指针加以保存,那们也一定能定义一个数组保存若干个函数名,这就是函数指针数组。正确使用函数指针数组的前提条件是,这若干个需要通过函数指针数组保存的函数必须有相同的输入、输出值。

//首先定义256个处理函数(及其实现)。
int function0( int *, int );
......
int function255( int *, int );

//其次定义函数指针数组,并给数组赋值。
void (*fun[256])( int *, int );

fun[0] = function0;
......
fun[255] = function255;

如果赋了不同的值给函数指针,那么调用者将调用不同地址的函数。赋值可以发生在运行时,这样使你能实现动态绑定。

下面我们来看一个具体的例子:

int test(int a)  
{  
	return a;  
} 

int main(void)
{  
	int (*fp)(int a);
	fp = test;                   //将函数test的地址赋给函数指针fp  
	cout<<fp(5)<<"|"<<(*fp)(10)<<endl;  //输出fp(5),这是标准c++的写法,(*fp)(10)这是兼容c语言的标准写法,两种同意,但注意区分,避免写的程序产生移植性问题!
	return 0;
} 

typedef定义可以简化函数指针的定义,在定义一个的时候感觉不出来,但定义多了就知道方便了,上面的代码改写成如下的形式:

int test(int a)  
{  
    return a;  
} 
  
int main(void)
{
	typedef int (*fp)(int a);        //注意,这里不是生命函数指针,而是定义一个函数指针的类型,这个类型是自己定义的,类型名为fp  
    fp fpi;                          //这里利用自己定义的类型名fp定义了一个fpi的函数指针!  
    fpi = test;  
    cout<<fpi(5)<<"|"<<(*fpi)(10)<<endl;  //输出fp(5),这是标准c++的写法,(*fp)(10)这是兼容c语言的标准写法,两种同意,但注意区分,避免写的程序产生移植性问题!
	return 0;
} 


 



 

指针的优势和缺点

指针是C语言的核心概念,也是C语言的特色和精华所在,更是初学者学习的难点所在。掌握了指针,才谈得上是真正掌握了C语言。 用C语言却不用指针,就像找个女人开房却聊天一晚上 使用指针可以带来如...
  • IOT_SONG
  • IOT_SONG
  • 2016-05-24 17:39:06
  • 2011

函数指针的好处

一般的时候用不到,主要还是一个简化结构和程序通用性的问题,也是实现面向对象编程的一种途径。简单的总结为: 1.       实现面向对象编程中的多态性 2.       回调函数 举两个...
  • newtonnl
  • newtonnl
  • 2012-07-07 15:35:37
  • 7271

函数指针的作用以及好处

//函数指针使用的例子#include #include char * fun(char * p1,char * p2) {   int i = 0;   i = strcmp(p1,p2);...
  • windyblankboy
  • windyblankboy
  • 2016-08-21 00:44:35
  • 3162

函数指针的好处、作用

C中函数指针的作用   项目中用到了很多封装在struct中的函数指针,以前在MFC里面经常用到则个作为回调函数,还以为是微软设计的特色呢。在网上查了一下它的用法,做个总结。   1)提供调...
  • wujiangguizhen
  • wujiangguizhen
  • 2013-12-06 00:29:00
  • 12910

浅谈函数指针

函数指针的概念,在潭浩强先生的C语言程序设计这本经典的教程中提及过,在大多数情况下我们使用不到,也忽略了它的存在。函数名实际上也是一种指针,指向函数的入口地址,但它又不同于普通的如int*、doubl...
  • Hackbuteer1
  • Hackbuteer1
  • 2011-10-18 11:43:17
  • 4627

指针的好处

转载▼     一、什么是指针 其实指针就像是其它变量一样,所不同的是一般的变量包含的是实际的真实的数据,而指针包含的是一个指向内存中某个位...
  • u011555996
  • u011555996
  • 2016-06-12 09:31:57
  • 1832

函数指针浅谈

1. 基本概念首先,应该明确: 程序运行期间,每个函数都会占用一段连续的内存空间。  函数名就是该函数所占内存区域的起始地址(也 称“入口地址”)  将函数的入口地址赋给一个指针变量,使该指 针变...
  • sinat_21595363
  • sinat_21595363
  • 2016-05-15 20:59:34
  • 223

浅谈====函数指针

1、函数指针及应用 我们先来看一下以下 的声明: int f(int); int  (*pf)(int)=&f;//&操作符可选;因为函数名被使用时总是由编译器把它 转换为函数指针; int...
  • vevenlcf
  • vevenlcf
  • 2013-08-28 20:57:56
  • 691

浅析STL 谓词 + 仿函数 + 函数指针(c)

一:起因 (0)提到C++ STL,首先被人想到的是它的三大组件:Containers(容器), Iterators(迭代器), Algorithms(算法)。容器为用户提供了常用的数据结构(如,ve...
  • u010700335
  • u010700335
  • 2015-01-30 20:57:21
  • 2432

函数指针及函数指针数组的妙用

函数指针及函数指针数组的妙用 笔者在开发某软件过程中遇到这样一个问题,前级模块传给我二进制数据,输入参数为 char* buffer和 int length,buffer是数据的首地址,leng...
  • u010925447
  • u010925447
  • 2017-07-04 10:52:01
  • 1184
收藏助手
不良信息举报
您举报文章:浅谈函数指针
举报原因:
原因补充:

(最多只允许输入30个字)