指向函数的指针声明和指向数组的指针声明容易混淆,原因在于函数和数组修饰符的优先级比指针修饰符的优先级高,因此通常需要使用圆括号。

  int *f1( );//一个返回值为 int* 的函数

  int ( *f2 )( );//一个指针,指向一个返回值为 int 的函数

  具有高优先级的数组修饰符存在同样的问题:

  const int N = 12;

  int *a1[ N ];//一个具有N个大小的数组,每个元素是 int *

  int ( *ap1 ) [ N ];//一个指针,指向一个具有N个 int 元素的数组

  理所当然,一旦拥有指向函数或数组的指针,就可以拥有指向这种指针的指针:

  int ( * * ap2 )[ N ];//一个指针,指向另一个指针,后者指向一个大小为N的 int 数组

  int * ( * ap3 )[ N ];//一个指针,指向一个大小为N的,每个元素为 int * 的数组

  int ( * * const fp2 )( ) =0; //一个常量指针,指向一个返回值为 int ,参数为空的函数指针

  注意,参数和返回值都会影响函数或函数指针的类型。

  char * ( *fp4 )( int ,int );

  char * ( *fp5 )( short , short )=0;

  fp4 = fp5;//错误!类型不匹配

  当函数和数组修饰符出现于同一个生命中时,事情的复杂性会变得难以估量。考虑入校常见但错误的声明,它试图声明一个函数指针数组:

  int ( * ) afp1[ N ];//语法错误!

  在以上错误的声明中,函数修饰符()的出现表示到了声明的末尾,而后面附加的afp1则表示一个语法错误的开始。这类似于一下数组声明写法:

  int [ N ] a2 ;//语法错误!

  这在Java中是合法的,但在C++中是非法的。函数指针数组的正确声明方式,是将数组名字和简单的函数指针声明放在一起。因此可以声明一个装有这些东西的数组:

  int ( * afp2 [ N ] ) ();//一个具有N个元素的数组,其元素类型为指向“返回值为int”的函数的指针

  至此,事情开始变得笨拙,typedef 闪亮登场的时刻到了:

  typedef  int ( * FP)()  ; //一个指向返回值为 int 的函数指针

  FP  afp3[ N ] ;// 一个具有N个“类型为FP”的元素的数组,该类型与afp2相同

  使用typedef可以简化复杂的声明语法,这也是对你代码维护者的关爱。使用typedef,甚至标准的set_new_handler函数的声明都变得简单多了:

  typedef void ( *new_handler )();

  new_handler set_new_handler( new_handler );

  如此一来,new_handler是指向这种函数的指针:它不带任何参数,返回void。而set_new_handler则是一个函数,带有一个new_handler作为参数,并返回一个new_handler作为结果。简单吧?如果尝试不用typedef,你的声望在哪些维护你的代码的人中将急剧下跌:

  void ( * set_new_handler( void (*)() ) ) ();//语法没错,但邪恶!

  还可以声明函数引用:

  int aFunc( double );

  int (&rFunc)( double ) = aFunc;

  函数引用很少用,其应用程度跟常量函数指针差不多:

  int (*const fFunc) (double) =aFunc;//常量函数指针

  数组引用确实提供了一些数组指针所未提供的额外能力,参见“数组形参[条款6]”中的讨论

处理函数和数组声明[条款17]---《C++必知必会》的更多相关文章

  1. 禁止或强制使用堆分配---《C++必知必会》 条款34

    有时候,指明一些特定类的对象不应该被分配到堆(heap)上是个好主意.通常这是为了确保该对象的析构函数一定会得到调用.维护对象本身(body object)的引用计数的句柄对象(handle obje ...

  2. 函数对象[条款18]---《C++必知必会》

    有时需要一些行为类似于函数指针的东西,但函数指针显得笨拙.危险而且过时(让我们承认这一点).通常最佳方式是使用函数对象(function object)取代函数指针. 与智能指针一样,函数对象也是一个 ...

  3. 学习javaScript必知必会(3)~数组(数组创建,for...in遍历,辅助函数,高级函数filter、map、reduce)

    一.数组: 1.js是弱语言,js中的数组定义时:不用指定数据类型.不用功指定数组长度:数组可以存储任何数据类型的数据 2.数组定义的[ ] 的实质: [] = new Array(); {} = n ...

  4. C++ 必知必会:条款16 指向成员函数的指针并非指针

    这一点与指向成员的指针类似,其实现可能更加复杂,因为成员函数同时还存在虚拟函数,需要动态绑定执行动作.当然这种属性是属于函数本身的,此处表达的是指针不涉及函数的属性问题. 1: class shape ...

  5. 成员函数查找[条款24]---《C++必知必会》

    调用一个成员函数,涉及三个步骤:第一步,编译器查找函数的名字:第二部,从可用候选者中选择最佳匹配函数:第三步,检查是否具有访问该函数的权限. #include<iostream> usin ...

  6. ES6必知必会 (二)—— 字符串和函数的拓展

    字符串的拓展 1.ES6为字符串添加了遍历器接口,因此可以使用for...of循环遍历字符串 2.字符串新增的 includes().startsWith().endsWidth() 三个方法用于判断 ...

  7. ES6必知必会 (一)—— 变量声明和结构赋值

    本文章属于个人对es6一些比较常用的语法的总结归纳,其主要参考阮一峰大神的<a href="http://es6.ruanyifeng.com//">ECMAScrip ...

  8. 特定于类的内存管理---《C++必知必会》 条款36

    我们可以量身定制 operator new 和 operator delete 用于某个类类型,而不是必须使用标准版的 operator new 和 operator delete. 注意:我们不可以 ...

  9. 学习javaScript必知必会(1)~js介绍、函数、匿名函数、自调用函数、不定长参数

    一.简单了解一下JavaScript(js) 1.什么是js? js:是网景公司开发的,是基于客户端浏览器, 面向(基于)对象.事件驱动式的页面脚本语言. 2.什么场景下使用到js? 表单验证.页面特 ...

随机推荐

  1. 【BZOJ】1647: [Usaco2007 Open]Fliptile 翻格子游戏(暴力)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1647 自己太弱...看题解.. 竟然是枚举第一行的放法,,,因为一定要全部变0,所以将前一行1的在这 ...

  2. 【BZOJ】1629: [Usaco2007 Demo]Cow Acrobats(贪心+排序)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1629 这题我想了很久都没想出来啊... 其实任意两头相邻的牛交换顺序对其它牛是没有影响的.. 那么我 ...

  3. Asp.Net MVC 把PartialView、View转换成字符串

    在开发中有时要在后台获得某个View 或者 PartialView 生成的字符串,只要你熟悉Asp.Net MVC  生命周期就能理解和敲出下面的代码.没什么高深的,直接上代码: 1,输出View H ...

  4. 修改CFileDialog的标题

    CFileDialog   f(TRUE);   f.m_ofn.lpstrTitle   =   "我的标题";   f.DoModal(); 设置标题! CFileDialog ...

  5. Android 安卓真机调试 出现Installation error: INSTALL_FAILED_UPDATE_INCOMPATIBLE....

    [2017-03-24 13:30:04 - DataVDemo06] Installing DataVDemo06.apk...[2017-03-24 13:30:08 - DataVDemo06] ...

  6. redis的简单操作

    今天在代码中使用hset存入redis中:jedis.hset(key.getBytes(), field.getBytes(), ObjectInfoPojo); 需要在redis中去验证数据是否存 ...

  7. webstorm配置内存参数,解决卡顿

    找到WebStorm.exe.vmoptions这个文件,路径如下webstorm安装主目录>bin>WebStorm.exe.vmoptions更改为第二行:-Xms526m第三行:-X ...

  8. [SCOI2010]传送带[三分]

    //point(AB)->point(CD) 距离满足下凸性,用三分套三分实现 #include<cmath> #include<cstdio> #include< ...

  9. [NOIP2017]宝藏 状压DP

    [NOIP2017]宝藏 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖 ...

  10. angular 2+ 路由守卫

    1. 定义接口名称 /domain/login-guard.ts export interface LoginGuard { data: any; msg: string; status: boole ...