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

函数存放在内存的代码区域内,它们同样有地址,我们如何能获得函数的地址呢?如果我们有一个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;

}

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

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

#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] ()这样地址带括号的操作,而函数指针不同它是一个例外,函数指针只所以这么叫它就是因为它是指向函数指向内存的代码区的指针,它被系统授予允许与() 号操作的权利,进行间接的函数调用,既然函数指针允许这么操作,那么被定义成函数指针的数组就一定是可以一样的操作的。

转载于:https://www.cnblogs.com/SweetDream/archive/2007/08/08/847202.html

C/C++中函数指针的含义(转)相关推荐

  1. 关于C++中函数指针的使用(包含对typedef用法的讨论)

    关于C++中函数指针的使用(包含对typedef用法的讨论) (一)简单的函数指针的应用. //形式1:返回类型(*函数名)(参数表) char (*pFun)(int); char glFun(in ...

  2. C++中函数指针数组的使用

    C++中函数指针数组的使用 来源:电脑教程在线(http://www.linuxdiyf.com/1/) 作者:linux 原文:C++中函数指针数组的使用(http://www.linuxdiyf. ...

  3. 关于C++中函数指针的使用

    关于C++中函数指针的使用(包含对typedef用法的讨论)  (一)简单的函数指针的应用. //形式1:返回类型(*函数名)(参数表)  char (*pFun)(int);  char glFun ...

  4. C++中函数指针的使用

    A function pointer is a variable that stores the address of a function that can later be called thro ...

  5. STC15分时内核中函数指针的使用问题

    2019独角兽企业重金招聘Python工程师标准>>> 基于前后台设计的系统随着功能的递增变得越来越难以维护, 所以决定为STC15F2K单片机编写一个基于时分的非抢占式内核,方便进 ...

  6. C++中函数指针的运用

    /** class_pointer.cxx** Created on: 2012-9-15* Author: Jesse Meng*/#include <iostream> using n ...

  7. 【C/C 】浅谈C/C 中函数指针与回调函数

    01.函数指针 1.1.函数指针定义 一个函数总是占用一段连续的内存区域,函数名在表达式中有时也会被转换为该函数所在内存区域的首地址,这和数组名非常类似.我们可以把函数的这个首地址(或称入口地址)赋予 ...

  8. C中函数指针的基本语法和思想

    1.C语言中函数的调用可分为直接调用和间接调用(函数指针),具体调用方法如下: int add(int a,int b) { return a+b; } void main() { add(1,2); ...

  9. C++ 类中函数指针的使用

    文章目录 函数指针用法 类中的成员函数接收函数指针 情况1 情况2 情况3 总结 函数指针用法 函数指针可以作为一个函数的参数,传不同的函数指针给这个函数就可以让其实现不能的功能.从而我们可以复用这个 ...

最新文章

  1. 如何重装计算机操作系统,自己如何重装笔记本电脑操作系统呢?
  2. dual orcal 虚拟表
  3. golang备份和恢复
  4. Java:log4j:WARN no appenders could be found for logger问题解决
  5. 【Python小程序】必备软件系列之文字识别提取,前台再也不同担心纸质转电子文件啦~
  6. (3)WebApi客户端调用
  7. Ambari2.7.4+HDP3.1.4.0中配置fair-scheduler
  8. 推荐一个一分钟就可以搭建好的静态文件服务器,基于nodejs
  9. MyBatis_ibatis和mybatis的区别【转】
  10. linux定时scp脚本,linux expect 实现定时scp的任务
  11. 数据库的移动 1007 sqlserver
  12. SpringBoot 自动配置原理
  13. Windows Embedded Webcast 2008年1月预告
  14. 产品研发过程管理专题——编写软件测试计划需要考虑的几个问题
  15. 基于内容的图像检索概述
  16. Gradle在Android中的基本使用
  17. 01-编写CMS注意事项
  18. 【python】计算圆周率到任意位支持任意位(速度快)
  19. 【JS】js中的和符号,或符号
  20. C语言某一身高下不同体重对应的BMI值表

热门文章

  1. 朴宥拉短片突破了几百万的观看量
  2. 手机老是应用无响应是怎么回事?
  3. linux系统升级后,手动编译的kernel无法启动问题
  4. word正在等候其他应用程序完成OLE操作
  5. sql 除以_避免SQL除以零错误的方法
  6. sql azure 语法_如何:Azure中SQL Server文件快照备份
  7. SQL Server系统数据库– msdb数据库
  8. sql 查询数据库索引重建_不良的数据库索引– SQL查询性能的杀手–建议
  9. BZOJ 3668: [Noi2014]起床困难综合症【二进制+贪心】
  10. win10下PLSQL Developer 连接ubuntu上安装的oracle 11g