C复杂声明举例
首先,一些国外的研究成果:
一个用英语解析复杂声明的网站:http://cdecl.org
图表说明复杂声明(英):http://c-faq.com/decl/spiral.anderson.html
另一个举例说明(英):http://www.unixwiz.net/techtips/reading-cdecl.html
知乎网友:https://www.zhihu.com/question/26931108
其次,写几个简单例子:
从未知量开始,一直推理到已知量。
例子1:char (*comp)()
- (*comp)
comp解引用,这说明comp是个指针 - (*comp)()
comp解引用后调用,这说明comp是个函数指针 - char (*comp)()
comp解引用后调用的返回值是char,这说明comp是个返回值为char的函数指针
例子2:char (*(*X())[]) ()
- X()
X调用,这说明X是个函数 - (*X())
X调用的返回值解引用,这说明X是个返回值为指针的函数 - 现在X是什么已经清楚了,现在的关键是其返回值的类型(用P表示)。
- (*X())[]
P解引用后可以用[]运算,这说明P解引用后还是个指针 - (*(*X())[])
P解引用后用[]运算之后的值还可以用*运算,这说明P解引用后再解引用还是个指针 - (*(*X())[]) ()
P解引用后用[]运算之后再用*运算后可以调用,这说明P三次解引用后是一个函数 - char (*(*X())[]) ()
该函数返回一个char - 总结: X是个返回值为指针的函数,该指针解引用三次后是一个返回值为char的函数。
最后:如果读C类型声明可以理解为渐进算法的话:
输入: C语言的类型声明, 例如: int **pi[5];
输出: 英文的C类型声明解释(由于语言语言, 中文读C类型声明非常不友好), 例如: pi is an Array of 5 Pointer to Pointer to int.
算法: (过于抽象的话, 后面有例子...)
I. 首先记住下面的规则:
i. 一个声明>>必须<<拥有一个基本类型(basic type), 这个基本类型>>总是<<在类型声明表达式的最左边. 然而一个声明可以具有>>0或更多<<个导出类型(derived type). (基本类型表请参照源链接)
ii. 导出类型由三个操作符(operator)构建:
i). *: 译为 pointer to, 切记介词to不可省略.
ii). [x]: 译为 array of, 切记介词of不可省略. (e.g. int ai[5]: ai is array of 5 int)
iii). ( ): 译为 function returning. 这里的小括号(parentheses)指的是构成函数指针的小括号而不是规定优先级的小括号. 区别: 构成函数指针的小括号永远出现在变量名的右边,而规定优先级的小括号永远将变量名包在里面.
iv). ii)中的三个操作符的优先级为: [x] 和( ) 优于*.
II. 首先由变量名以及处于最左边的基本类型构成不完整的解释. 然后从变量名开始由内向外解释声明, 遵从"能向右解读就向右解读, 必须向左解读时再向左解读".
Example: 就用提问里第二个 char (*(*x( ))[ ]) ( ); 解释上面的算法:
Step 1: (首先由变量名以及处于最左边的基本类型构成不完整的解释.): x is ... char. 下面逐步在"..."处增添关于x的解释.
Step 2: (由于( ) 的优先级高于*, 向右解读): x( ): x is a function returning ... char.
Step 3: (遇到右括号, 向左解读): *x( ): x is a function returning pointer to ... char.
Step 4: (由于[ ] 优先级高于*, 向右解读): (*x( ))[ ]: x is a function returning pointer to array of ... char.
Step 5: (遇到右括号, 向左解读): *(*x( ))[ ]: x is a function returning pointer to array of pointers to ... char.
Step 6: (最后的右边的括号): (*(*x( ))[ ]) ( ): x is a function returning pointer to array of pointers to function returning char.
结果和cdecl的输出一致.
C复杂声明举例的更多相关文章
- jsp基础语言-jsp声明
jsp声明的语法格式:<%! 声明代码 %> jsp声明的意义:用来定义在程序中使用到的变量.方法等.最后要以“:”结尾. jsp声明举例: <%! int a=100,b=200; ...
- MIC中函数和变量的声明
c++/c使用 __declspec(target(mic))函数或变量声明 或 __attribute__((target(mic)))函数或变量声明 举例如下: __attribute__((ta ...
- Java变量常量声明和定义
一.常量和变量 1.常量变量定义 在程序中存在大量的数据来代表程序的状态,其中有些数据在程序的运行过程中值会发生改变,有些数据在程序运行过程中值不能发生改变,这些数据在程序中分别被叫做变量和常量. 2 ...
- Ajax.BeginForm方法 参数
感谢博主 http://www.cnblogs.com/zzgblog/p/5454019.html toyoung 在Asp.Net的MVC中的语法,在Razor页面中使用,替代JQuery的Aja ...
- Java学习之注解Annotation实现原理
前言: 最近学习了EventBus.BufferKinfe.GreenDao.Retrofit 等优秀开源框架,它们新版本无一另外的都使用到了注解的方式,我们使用在使用的时候也尝到不少好处,基于这种想 ...
- JavaWeb之XML详解
XML语言 什么是XML? XML是指可扩展标记语言(eXtensible Markup Language),它是一种标记语言,很类似HTML.它被设计的宗旨是传输数据,而非显示数据. XML标签没有 ...
- Ajax.ActionLink参数详解
该语法会生成一个a标签,点击a标签会执行一个Ajax请求. 有12个方法重载,下面详解方法中的各项参数: 参数一:linkText string类型 说明:链接显示的文字内容 参数二:actionNa ...
- Ajax.BeginForm参数详解
在Asp.Net的MVC中的语法,在Razor页面中使用,替代JQuery的Ajax使用,方便快捷. 使用Ajax.BeginForm方法会生成一个form表单,最后以Ajax的方式提交表单数据:需要 ...
- 【JAVA与XML、dtd约束、Schema约束】
一.XML. (1)XML:Extensible Markup Language (2)XML是一种标记语言. (3)XML的设计宗旨是传输数据,而不是显示数据. (4)XML标签没有被预定义,即使用 ...
随机推荐
- Unity3d通用工具类之数据配置加载类
今天,我们来讲讲游戏中的数据配置加载. 什么是游戏数据加载呢?一般来说游戏中会有场景地图. 按照国际惯例,先贴一张游戏场景的地图: 在这张地图上,我们可以看到有很多正六边形,正六边形上有树木.岩石等. ...
- shell执行时文件命名导致的错误
1.脚本check_nginx.sh的内容如下: #!/bin/bash count=$(ps -ef | grep nginx | grep -v grep | wc -l) echo $count ...
- cocos2d-x v3.0各个环境下创建项目以及编译、执行官方DEMO
摘自:https://github.com/cocos2d/cocos2d-x/ 怎样创建一个新项目 How to start a new game Download the code from co ...
- OpenCV学习(2) OpenCV的配置
下面我们在VS2010中编写一个简单的OpenCV程序,来看看如何在程序中使用OpenCV. 创建一个新的Win32 控制台程序,附加选项为空工程(empty project),并添加一个 ...
- linux 网络设备驱动
linux 网络驱动 谨以此文纪念过往的岁月 一.前言在linux中网络驱动也是一个大头,如何去理解网络驱动是作为一个linux驱动工程师必备的技能.不过同样的设备,在不同人的手中会有不同的效果,其原 ...
- JSP学习笔记(二):动作元素
与JSP指令元素不同的是,JSP动作元素在请求处理阶段起作用.JSP动作元素是用XML语法写成的. 利用JSP动作可以动态地插入文件.重用JavaBean组件.把用户重定向到另外的页面.为Java插件 ...
- 转载 C++实现的委托机制
转载 C++实现的委托机制 1.引言 下面的委托实现使用的MyGUI里面的委托实现,MyGUI是一款强大的GUI库,想理解更多的MyGUI信息,猛击这里http://mygui.info/ 最终的代码 ...
- 缩进与对齐——正确地使用Tab和空格
写代码时大家都会使用缩进(indentation)和对齐(alignment),这是两个相关而又不同的概念,两者都是为了提高代码的可读性.缩进出现在一行的最左边,目的是明显地区分开包含与被包含的代码: ...
- JS-获取图片地址
var url=document.getElementById("a001").src; 或var url=document.getElementById("a001&q ...
- public类型中internal成员
今天遇到一问题,找到下面的两篇文章,研究比较深入,特转了一下, 最近除了搞ASP.NET MVC之外,我也在思考一些编程实践方面的问题.昨天在回家路上,我忽然对一个问题产生了较为清晰的认识.或者说,原 ...