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 ...
随机推荐
- js获取屏幕宽高
最近想自己实现一个全屏滚动. 结果一开始就遇到了问题.因为不知道如何获取一个页面屏幕的高度. 网上所有的博客都是复制粘贴. 网页可见区域宽:document.body.clientWidth 网页可见 ...
- IntelliJ IDEA 内存优化最佳实践
本文作者在和同事的一次讨论中发现,对 IntelliJ IDEA 内存采用不同的设置方案,会对 IDE 的速度和响应能力产生不同的影响. Don't be a Scrooge and give you ...
- JavaScript 随机数
JavaScript内置函数random(seed)可以产生[0,1)之间的随机数,若想要生成其它范围的随机数该如何做呢? 生成任意范围的随机数 //生成[100,120)之间的随机数 Math.fl ...
- 图标字体 VS 雪碧图——图标字体应用实践
本文介绍使用图标字体和SVG取代雪碧图的方法.雪碧图是很多网站经常用到的一种技术,但是它有缺点:高清屏会模糊.无法动态变化如hover时候反色.而使用图标字体可以完美解决上述问题,同时具备兼容性好,生 ...
- Boost条件变量condition_variable_any
Boost条件变量可以用来实现线程同步,它必须与互斥量配合使用.使用条件变量实现生产者消费者的简单例子如下,需要注意的是cond_put.wait(lock)是在等待条件满足.如果条件不满足,则释放锁 ...
- Android的历史与花边
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 历史 现在的Android如日中天.每天150万部的Android设备被激活,全球 ...
- python入门-python解释器执行
最近由于公司需要,接触了python这门神奇的语言,给我的感觉就是开发快速和代码简洁. 开始还是先罗列一下解释性语言和编译性语言的差别吧0.0! 编译性语言:是在程序运行前,需要专门的一个编译过程 ...
- 4.6 .net core依赖注入的封装
现在流行的系统一般都采用依赖注入的实现方式,利用DI容器来直接获取所用到的类/接口的实例..net core也一样采用DI的方式,提供了DI容器的接口IServiceCollection,并提供了基于 ...
- 【转】Android SDK Samples,学习Android的好方法
转载地址:http://blog.csdn.net/rowland001/article/details/50886288 从今天开始呢,我要开始学习Google家自己出的Android代码示例,总觉 ...
- Android中的 init.rc文件简介
init.rc脚本是由Android中linux的第一个用户级进程init进行解析的. init.rc 文件并不是普通的配置文件,而是由一种被称为"Android初始化语言"(An ...