曾经在书上看到函数指针相关的都没怎么重视。可是近期在实际的工作中却派上了用场。所以认真地学习了一遍。

函数指针的申明

申明一个函数指针非常easy,就是将函数申明中的函数名替换为一个指针就可以:

C/C++
int test(int para1, double *para2); // 函数申明
int (*pf)(int para1, double *para2); // 函数指针申明

NOTE: 必须在申明中用括号将*pf括起来,由于括号的优先级比*运算符高。因此:

C/C++
int (*pf)(int para1, double *para2); // 一个指向函数的指针
int *pf(int para1, double *para2); // 一个返回指针的函数

申明完函数指针的下一步就是对函数指针赋值。也就是将函数指针指向一个类型匹配的函数(这跟基本类型的指针一致),一个函数的函数名就是该函数的地址

C/C++
pf = test;
int (*pf1)(int para1, double *para2) = test; // 也能够在函数指针申明时完毕初始化

C++11有了自己主动类型判断功能,就简单了非常多:

C++11 code
auto pf = test;

使用函数指针调用函数

(*pf)扮演的角色与函数名同样,因此使用(*pf)时,仅仅须要将它看做函数名就可以:

C/C++
int n = 0;
double d = 0.0;
int r = 0;
r = (*pf)(n, &d);
r = pf(n, &d); // 这样的方式C/C++也是同意的

函数指针数组

我们有可能还须要用到函数指针数组。示比例如以下:

C/C++
int test1(int para1, double *para2); // 函数申明
int test2(int para1, double *para2); // 函数申明
int test3(int para1, double *para2); // 函数申明 int (*pfArray[3])(int para1, double *para2) = {test1, test2, test3}; // 函数指针数组申明及初始化
r = *pfArray[0](n, &d); // 函数调用

能够看到这样的方式使用函数指针是比較麻烦的。试想假设上面的函数返回值是const指针,而我们又想将函数指针数组申明为不可更改的,那这个const应该加到哪?这里提供另外一个比較简单的解决方法,也就是以下将要说到的使用typedef进行简化。

使用typedef进行简化

C/C++
typedef int (*p_fun)(int para1, double *para2); // 这样我们就能像使用一个普通类型那样来使用函数指针了
p_fun pf = test;
const p_fun pf1 = test; // 常量函数指针申明及初始化,注意跟一般的const数据类型一样。常量函数指针必须在申明时完毕初始化
p_fun pfArray[3] = {test1, test2, test3};
const p_fun pfArray1[3] = {test1, test2, test3}; // 常量函数指针数组申明及初始化

It's that easy!


參考书籍:《C++ Primer Plus (第6版)中文版》

C/C++学习:函数指针的更多相关文章

  1. 函数指针的应用学习Demo

    学习函数指针的应用 ,简单demo #include "stdafx.h" #include "SubClass.h"; //函数指针 typedef int ...

  2. iOS学习09C语言函数指针

    本次主要学习和理解函数指针 1.函数指针 void printValue(int number) { printf("number = %d\n", number); } int ...

  3. C++学习之函数指针

     C++学习之函数指针          和数据项类似,函数也有地址,函数的地址是存储在机器语言代码的内存的开始地址.通常,这些地址对用户而言,不重要也没什么用处,但对程序而言,它却很有用. 一.函数 ...

  4. C++学习之普通函数指针与成员函数指针

    函数指针(function pointer)是通过指向函数的指针间接调用函数.相信很多人对指向一般函数的函数指针使用的比较多,而对指向类成员函数的函数指针则比较陌生.我最近也被问到了这方面的问题,心中 ...

  5. [C++学习笔记14]动态创建对象(定义静态方法实现在map查找具体类名对应的创建函数,并返回函数指针,map真是一个万能类)good

    [C++学习笔记14]动态创建对象   C#/Java中的反射机制 动态获取类型信息(方法与属性) 动态创建对象 动态调用对象的方法 动态操作对象的属性 前提:需要给每个类添加元数据 动态创建对象 实 ...

  6. C语言学习019:函数指针

    在C语言中,函数名也是指针变量,比如创建了一个add(int n,int m)的函数的同时也创建了一个名为add的指针变量,因此我们可以把函数指针当作一种类型为它赋值.当作参数传递等操作 C语言创建函 ...

  7. iOS学习之C语言函数指针

    通过函数名调用函数: int max = maxValue(4, 5); printf("max = %d\n", max);     函数类型:int (int, int) 1. ...

  8. C++学习笔记之函数指针

    与数据项类似,函数也有地址.函数的地址是存储其机器语言代码的内存开始的地方. 一.函数指针的基础知识 假设要设计一个名为estimate()的函数,估算编写指定行数代码所需时间,并且希望不同的程序员都 ...

  9. C++学习笔记(八):函数重载、函数指针和函数对象

    函数重载 函数重载是指在同一作用域内,可以有一组具有相同函数名,不同参数列表的函数,这组函数被称为重载函数.重载函数通常用来命名一组功能相似的函数,这样做减少了函数名的数量,避免了名字空间的污染,对于 ...

随机推荐

  1. 基于Spring boot的web项目搭建教程(一)

    前言: 本教程参考了大量前辈的代码,在此不方便一一列举.本教程使用IDEA开发工具搭建项目,对于本人的IDEA已经集成了某些插件,比如Lombok,Thymeleaf,yml等插件,这些插件不在文中提 ...

  2. jQuery不熟点总结

     jQuery 事件 1 .trigger() 方法触发被选元素的指定事件类型. 2 .delegate() 事件委派  1.不占内存2.可以给未来元素(后期动态添加的元素)添加事件. 2.  添加元 ...

  3. 如何用SVG写一个环形进度条以及动画

    本次案例主要使用了svg的三个元素,分别为circle.text.path,关于svg的介绍大家可以看MDN上的相关教程,传送门 由于svg可以写到HTML中,所以这里我们就可以很方便的做进度条加载动 ...

  4. css中单位的使用

    css中许多的属性都需要添加长度,而长度一般由数字和单位构成,如1px,1.5em,2vh:也可以省略单位,如line-height:1.5,表示行高为字体大小的1.5倍: 长度单位一般也分为相对长度 ...

  5. OData + jqgrid 部署在IIS 8.0上可增加但不能删除修改问题

    解决方法: <system.webServer>里添加 <modules> <remove name="WebDAVModule" /> < ...

  6. python爬虫:读取PDF

    下面的代码可以实现用python读取PDF,包括读取本地和网络上的PDF. pdfminer下载地址:https://pypi.python.org/packages/source/p/pdfmine ...

  7. (转) shiro权限框架详解06-shiro与web项目整合(上)

    http://blog.csdn.net/facekbook/article/details/54947730 shiro和web项目整合,实现类似真实项目的应用 本文中使用的项目架构是springM ...

  8. Day 12 闭包函数,装饰器

    闭包函数 回顾: 1.函数对象:可以将定义在函数内的函数返回到全局使用.从而打破了函数层级限制 2.名称空间与作用域:作用域关系在函数定义阶段时就已经固定死了,与调用位置无关,即在任意位置调用函数都需 ...

  9. PostgreSQL 安装配置 (亲测可用)

    转自:http://blog.csdn.net/jesseyoung/article/details/41348835 受作者博客限制,请访问上面的链接 ---------- 下面是另一个转载 --- ...

  10. 原生node写一个静态资源服务器

    myanywhere 用原生node做一个简易阉割版的anywhere静态资源服务器,以提升对node与http的理解. 相关知识 es6及es7语法 http的相关网络知识 响应头 缓存相关 压缩相 ...