分享
 
 
 

C/C++中函数指针的含义

王朝c/c++·作者佚名  2008-06-01
窄屏简体版  字體: |||超大  

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

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

定义一个指向函数的指针用如下的形式,以上面的test()为例: int (*fp)(int a);//这里就定义了一个指向函数的指针 函数指针不能绝对不能指向不同类型,或者是带不同形参的函数,在定义函数指针的时候我们很轻易犯如下的错误。int *fp(int a);//这里是错误的,因为按照结合性和优先级来看就是先和()结合,然后变成了一个返回整形指针的函数了,而不是函数指针,这一点尤其需要注重! 下面我们来看一个具体的例子:#include <iostream>

#include <string>

using namespace std;

int test(int a);

void main(int argc,char* argv[])

{

cout<<test<<endl;//显示函数地址

int (*fp)(int a);

fp=test;//将函数test的地址赋给函数学指针fp

cout<<fp(5)<<""<<(*fp)(10)<<endl;

//上面的输出fp(5),这是标准c++的写法,(*fp)(10)这是兼容c语言的标准写法,两种同意,但注重区分,避免写的程序产生移植性问题!

cin.get();

}

int test(int a)

{

return a;

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

#include <string>

using namespace std;

int test(int a);

void main(int argc,char* argv[])

{

cout<<test<<endl;

typedef int (*fp)(int a);//注重,这里不是生命函数指针,而是定义一个函数指针的类型,这个类型是自己定义的,类型名为fp

fp fpi;//这里利用自己定义的类型名fp定义了一个fpi的函数指针!

fpi=test;

cout<<fpi(5)<<""<<(*fpi)(10)<<endl;

cin.get();

}

int test(int a)

{

return a;

}

更多内容请看C/C++技术专题专题,或

函数指针同样是可以作为参数传递给函数的,下面我们看个例子,仔细阅读你将会发现它的用处,稍加推理可以很方便我们进行一些复杂的编程工作。

//-------------------该例以上一个例子作为基础稍加了修改-----------------------------

#include <iostream>

#include <string>

using namespace std;

int test(int);

int test2(int (*ra)(int),int);

void main(int argc,char* argv[])

{

cout<<test<<endl;

typedef int (*fp)(int);

fp fpi;

fpi=test;//fpi赋予test 函数的内存地址

cout<<test2(fpi,1)<<endl;//这里调用test2函数的时候,这里把fpi所存储的函数地址(test的函数地址)传递了给test2的第一个形参

cin.get();

}

int test(int a)

{

return a-1;

}

int test2(int (*ra)(int),int b)//这里定义了一个名字为ra的函数指针

{

int c=ra(10)+b;//在调用之后,ra已经指向fpi所指向的函数地址即test函数

return c;

} 利用函数指针,我们可以构成指针数组,更明确点的说法是构成指向函数的指针数组,这么说可能就轻易理解的多了。#include <iostream>

#include <string>

using namespace std;

void t1(){cout<<"test1";}

void t2(){cout<<"test2";}

void t3(){cout<<"test3";}

void main(int argc,char* argv[])

{

void* a[]={t1,t2,t3};

cout<<"比较t1()的内存地址和数组a[0]所存储的地址是否一致"<<t1<<""<<a[0]<<endl;

cout<<a[0]();//错误!指针数组是不能利用数组下标操作调用函数的

typedef void (*fp)();//自定义一个函数指针类型

fp b[]={t1,t2,t3}; //利用自定义类型fp把b[]定义趁一个指向函数的指针数组

b[0]();//现在利用指向函数的指针数组进行下标操作就可以进行函数的间接调用了;

cin.get();

} 仔细看上面的例子可能不用我多说大家也会知道是怎么一会事情了,最后我们做一个重点小结,只要记住这一点,对于理解利用函数指针构成数组进行函数间接调用就很轻易了! void* a[]={t1,t2,t3};

cout<<"比较t1()的内存地址和数组a[0]所存储的地址是否一致"<<t1<<""<<a[0]<<endl;

cout<<a[0]();//错误!指针数组是不能利用数组下标操作调用函数的 上面的这一小段中的错误行,为什么不能这么调用呢?

前一篇教程我们已经说的很清楚了,不过在这里我们还是复习一下概念,指针数组元素所保存的只是一个内存地址,既然只是个内存地址就不可能进行a[0]()这样地址带括号的操作,而函数指针不同它是一个例外,函数指针只所以这么叫它就是因为它是指向函数指向内存的代码区的指针,它被系统授予答应与()括号操作的权利,进行间接的函数调用,既然函数指针答应这么操作,那么被定义成函数指针的数组就一定是可以一样的操作的。

更多内容请看C/C++技术专题专题,

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有