学习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++函数指针总结的更多相关文章

  1. C++虚函数和函数指针一起使用

    C++虚函数和函数指针一起使用,写起来有点麻烦. 下面贴出一份示例代码,可作参考.(需要支持C++11编译) #include <stdio.h> #include <list> ...

  2. 为什么 C++ 中成员函数指针是 16 字节?

    当我们讨论指针时,通常假设它是一种可以用 void * 指针来表示的东西,在 x86_64 平台下是 8 个字节大小.例如,下面是来自 维基百科中关于 x86_64 的文章 的摘录: Pushes a ...

  3. C与指针(结构体指针,函数指针,数组指针,指针数组)定义与使用

    类型 普通指针 指针数组(非指针类型) 数组指针 结构体指针 函数指针 二重指针 定义方式 int *p; int *p[5]; int (*p)[5]; int a[3][5]; struct{.. ...

  4. 结构体内嵌函数指针实现C语言面向对象

    结构体内嵌函数指针 #include<stdio.h> void say(int age) { printf("我%d岁了\n",age); } struct stud ...

  5. 用typedef定义函数指针的问题

    在学习windows API的时候,遇到下面这段代码   以前见过的typedef的用法都是给一个数据类型取一个别名 typedef oldTypeName newTypeName   这种给数据类型 ...

  6. 你必须知道的指针基础-7.void指针与函数指针

    一.不能动的“地址”—void指针 1.1 void指针初探 void *表示一个“不知道类型”的指针,也就不知道从这个指针地址开始多少字节为一个数据.和用int表示指针异曲同工,只是更明确是“指针” ...

  7. objective-c中的@selector()和 c /c++的函数指针

    先看tomcat里用到的代码: //然后开始动画 //把图片放到animationImages,接受数组参数 self.tom.animationImages = arrayImage; //设置时间 ...

  8. C++基础——函数指针 函数指针数组

    ==================================声明================================== 本文版权归作者所有. 本文原创,转载必须在正文中显要地注明 ...

  9. QT中使用函数指针

    想仿命令行,所以定义了一个类,让一个String 对应一个 function,将两者输入list容器. 类中定义了 QString commandStr; void (MainWindow::*com ...

随机推荐

  1. YYModel 源码解读(一)之YYModel.h

    #if __has_include(<YYModel/YYModel.h>) FOUNDATION_EXPORT double YYModelVersionNumber; FOUNDATI ...

  2. WeText项目:一个基于.NET实现的DDD、CQRS与微服务架构的演示案例

    最近出于工作需要,了解了一下微服务架构(Microservice Architecture,MSA).我经过两周业余时间的努力,凭着自己对微服务架构的理解,从无到有,基于.NET打造了一个演示微服务架 ...

  3. LinqToDB 源码分析——前言

    记得笔者进入公司的时候接触的第一个ORM框架是Entity Framework.为了Entity Framework也看了不些的英文资料(不是笔者装B哦).正式使用三个月后.笔者对他有一个全面性的认识 ...

  4. Node基础篇(文件操作)

    文件操作 相关模块 Node内核提供了很多与文件操作相关的模块,每个模块都提供了一些最基本的操作API,在NPM中也有社区提供的功能包 fs: 基础的文件操作 API path: 提供和路径相关的操作 ...

  5. mvc过滤器学习(1)

    mvc 过滤器结构图 AuthorizeAttribute AuthorizeAttribute是IAuthorizationFilter的默认实现,添加了Authorize特性的Action将对用户 ...

  6. JavaWeb_day03_员工信息添加修改删除

    day03员工的添加,修改,删除 修改功能 思路 : 点击修改员工数据之后,跳转到单行文本,查询要修改的员工id的全部信息,主键id设置为readonly,其余的都可以修改, 修改之后,提交按钮,提交 ...

  7. springmvc<一>一种资源返回多种形式【ContentNegotiatingViewResolver】

    restful服务中一个重要的特性就是一种资源可以有多种表现形式,在springmvc中可以使用ContentNegotiatingViewResolver这个视图解析器来实现这种方式. 描述资源的三 ...

  8. Windows安装RabbitMQ集群的几个注意点

    记录一下RabbitMQ在windows平台下安装的几个注意点- -,好记性不如烂笔头 安装过程与Linux安装一致,教程参照官网集群配置:此处只列举出几个注意点: 1. erlang的版本需要一致, ...

  9. MySQL大数据优化

    我们考虑的情况是在你的数据量很大的情况下,千万级别的数据量.不要当我们的请求响应时间已经让我无法忍受的时候,再来想起来优化,可能有点迟了.因为可能会丢失很多潜在的价值客户.所以,在我们当初设计表,或者 ...

  10. IIS7 应用程序池自动回收关闭的解决方案

    在ASP.NET Application中加入某个定时任务,那想必一定是用一个线程在不停地做定时计算,在自己的ASP.NET应用程序中加入了Quartz.NET框架 夜间或者网站在经过无访问阶段后,后 ...