C++函数指针总结
学习c++的过程中,指针是难点,熟悉了指针之后,还有一个让人很蛋疼的难点,那就是函数指针了。本博文详细介绍一下常见的各种坑爹的函数指针。
至于指针的详细学习,推荐这篇博文C++指针详解
与数据一样,函数也有地址,函数的地址就是内存中存放函数语言代码的起始地址。函数指针就是指向这个地址。函数指针所指向的类型,就是函数本身。我们知道,指针所指向类型代表了指针所指向的内存区域的大小。所以函数指针所指向的类型,就是函数在内存中所占据内存的大小。知道了函数的起始地址和大小,所以函数指针可以很轻易的代替函数完成函数调用。
一、最简单的函数指针
变量都包括声明和赋值,指针不例外,函数指针也不例外。我们来看一个简单的函数:
void add(int a, int b){
cout << a + b << endl;
}
一个简单的加法计算并输出到命令行的函数。
那么如何通过函数指针来调用它呢?
1、声明:
void (*p1)(int a, int b);
函数指针的声明很简单,基本就是通过一个指针把函数名替换。指针p1的类型为void (*) (int a,int b),表明指针是一个指向某个函数的指针,指针指向的类型为void () (int a,int b)
2、赋值:
p1 = add;
3、也可以直接定义:
void (*p1)(int a, int b) = add;
注意,函数void add(int a,int b)的函数名add就是函数的地址。将地址add赋值给指针p1,那么就可以通过函数指针p1直接调用函数了。
4、调用:
(*p1)(, );
p1(, );
注意!出于历史原因以上2种方式都是可以调用函数的。
二、包含多个函数指针的数组
有时候有这种情况,有一个数组,数组中的每个元素都是一个函数指针,该怎么定义这个数组呢?
1、解释*p[n]和(*p)[n]
我们知道,[]运算符的优先级要高于*,所以,p[3]表示含有3个元素的数组,而*p[3] 前面的 " * " 指明了数组中元素的类型,即*p[3]表示一个指向3个指针的数组。
p[3]表示含有3个元素的数组,那么(*p)[3]就是用 *p 替换了 p,很容易想到,(*p)[3] 表示指向一个包含3个元素的数组的指针。
2、声明:
void (*p2[])(int a, int b);
数组名为p2,数组大小为2,数组中元素类型为void (*)(int a, int b),表明元素是一个指向某个函数的指针,指针指向的类型为void () (int a,int b)。
3、赋值:
p2[] = add;
理解上跟上面是一样的。
4、调用:
p2[](,);
(*p2[])(,);
同样是2种方式都可以。
三、指向“包含多个函数指针的数组“的指针
这个标题好像有点拗口。简而言之,这个指针指向上文中的 “包含多个函数指针的数组” 。其实很简单,说白了,就是把上文中的p2用一个指针来代替。
1、声明:
void (*(*p3)[])(int a, int b);
可以看到,无非就是把p2用*p3代替。
2、赋值,注意,既然是指针,使用前必须初始化:
p3 = &p2;
(*p3)[] = add;
注意!既然实质上就是把p2用*p3代替,c++11可以很简单的这样直接定义:auto p3 = &p2; 代替了void (*(*p3)[2])(int a, int b)= &p2;
3、调用:
(*p3)[](, );
(*(*p3)[])(, );
C++函数指针总结的更多相关文章
- C++虚函数和函数指针一起使用
C++虚函数和函数指针一起使用,写起来有点麻烦. 下面贴出一份示例代码,可作参考.(需要支持C++11编译) #include <stdio.h> #include <list> ...
- 为什么 C++ 中成员函数指针是 16 字节?
当我们讨论指针时,通常假设它是一种可以用 void * 指针来表示的东西,在 x86_64 平台下是 8 个字节大小.例如,下面是来自 维基百科中关于 x86_64 的文章 的摘录: Pushes a ...
- C与指针(结构体指针,函数指针,数组指针,指针数组)定义与使用
类型 普通指针 指针数组(非指针类型) 数组指针 结构体指针 函数指针 二重指针 定义方式 int *p; int *p[5]; int (*p)[5]; int a[3][5]; struct{.. ...
- 结构体内嵌函数指针实现C语言面向对象
结构体内嵌函数指针 #include<stdio.h> void say(int age) { printf("我%d岁了\n",age); } struct stud ...
- 用typedef定义函数指针的问题
在学习windows API的时候,遇到下面这段代码 以前见过的typedef的用法都是给一个数据类型取一个别名 typedef oldTypeName newTypeName 这种给数据类型 ...
- 你必须知道的指针基础-7.void指针与函数指针
一.不能动的“地址”—void指针 1.1 void指针初探 void *表示一个“不知道类型”的指针,也就不知道从这个指针地址开始多少字节为一个数据.和用int表示指针异曲同工,只是更明确是“指针” ...
- objective-c中的@selector()和 c /c++的函数指针
先看tomcat里用到的代码: //然后开始动画 //把图片放到animationImages,接受数组参数 self.tom.animationImages = arrayImage; //设置时间 ...
- C++基础——函数指针 函数指针数组
==================================声明================================== 本文版权归作者所有. 本文原创,转载必须在正文中显要地注明 ...
- QT中使用函数指针
想仿命令行,所以定义了一个类,让一个String 对应一个 function,将两者输入list容器. 类中定义了 QString commandStr; void (MainWindow::*com ...
随机推荐
- HTML5 学习总结(四)——canvas绘图、WebGL、SVG
一.Canvas canvas是HTML5中新增一个HTML5标签与操作canvas的javascript API,它可以实现在网页中完成动态的2D与3D图像技术.<canvas> 标记和 ...
- Python笔记之不可不练
如果您已经有了一定的Python编程基础,那么本文就是为您的编程能力锦上添花,如果您刚刚开始对Python有一点点兴趣,不怕,Python的重点基础知识已经总结在博文<Python笔记之不可不知 ...
- iOS 保存、读取与应用状态
固化 对于大多数iOS应用,可以将其功能总结为:提供一套界面,帮助用户管理特定的数据.在这一过程中,不同类型的对象要各司其职:模型对象负责保存数据,视图对象负责显示数据,控制器对象负责在模型对象与视图 ...
- jdk源码分析红黑树——插入篇
红黑树是自平衡的排序树,自平衡的优点是减少遍历的节点,所以效率会高.如果是非平衡的二叉树,当顺序或逆序插入的时候,查找动作很可能会遍历n个节点 红黑树的规则很容易理解,但是维护这个规则难. 一.规则 ...
- JAVA的序列化和持久化的区别与联系
持久化(Persistence) 即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘).持久化的主要应用是将内存中的对象存储在关系型的数据库中,当然也可以存储在磁盘文件中.XML数据文 ...
- .net FTP上传文件
FTP上传文件代码实现: private void UploadFileByWebClient() { WebClient webClient = new WebClient(); webClient ...
- cmd命令汇总
一 cmd 命令 cmd命令大全(第一部分) winver---------检查Windows版本 wmimgmt.msc----打开windows管理体系结构(WMI) wupdmgr------ ...
- HTML5本地存储Localstorage
什么是localstorage 前几天在老项目中发现有对cookie的操作觉得很奇怪,咨询下来是要缓存一些信息,以避免在URL上面传递参数,但没有考虑过cookie会带来什么问题: ① cookie大 ...
- getting started with transformjs
Introduction In the past two years, more and more friends for mobile web development have used the t ...
- Linux安装xwindow图形界面(转载)
http://jingyan.baidu.com/article/7f766daf42ce984100e1d045.html 1.检查Linux系统是否能够联网. 2.执行命令 yum -y grou ...