首先,一些国外的研究成果:

一个用英语解析复杂声明的网站: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)()

  1. (*comp)
    comp解引用,这说明comp是个指针
  2. (*comp)()
    comp解引用后调用,这说明comp是个函数指针
  3. char (*comp)()
    comp解引用后调用的返回值是char,这说明comp是个返回值为char的函数指针

例子2:char (*(*X())[]) ()

  1. X()
    X调用,这说明X是个函数
  2. (*X())
    X调用的返回值解引用,这说明X是个返回值为指针的函数
  3. 现在X是什么已经清楚了,现在的关键是其返回值的类型(用P表示)。
  4. (*X())[]
    P解引用后可以用[]运算,这说明P解引用后还是个指针
  5. (*(*X())[])
    P解引用后用[]运算之后的值还可以用*运算,这说明P解引用后再解引用还是个指针
  6. (*(*X())[]) ()
    P解引用后用[]运算之后再用*运算后可以调用,这说明P三次解引用后是一个函数
  7. char (*(*X())[]) ()
    该函数返回一个char
  8. 总结: 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复杂声明举例的更多相关文章

  1. jsp基础语言-jsp声明

    jsp声明的语法格式:<%! 声明代码 %> jsp声明的意义:用来定义在程序中使用到的变量.方法等.最后要以“:”结尾. jsp声明举例: <%! int a=100,b=200; ...

  2. MIC中函数和变量的声明

    c++/c使用 __declspec(target(mic))函数或变量声明 或 __attribute__((target(mic)))函数或变量声明 举例如下: __attribute__((ta ...

  3. Java变量常量声明和定义

    一.常量和变量 1.常量变量定义 在程序中存在大量的数据来代表程序的状态,其中有些数据在程序的运行过程中值会发生改变,有些数据在程序运行过程中值不能发生改变,这些数据在程序中分别被叫做变量和常量. 2 ...

  4. Ajax.BeginForm方法 参数

    感谢博主 http://www.cnblogs.com/zzgblog/p/5454019.html toyoung 在Asp.Net的MVC中的语法,在Razor页面中使用,替代JQuery的Aja ...

  5. Java学习之注解Annotation实现原理

    前言: 最近学习了EventBus.BufferKinfe.GreenDao.Retrofit 等优秀开源框架,它们新版本无一另外的都使用到了注解的方式,我们使用在使用的时候也尝到不少好处,基于这种想 ...

  6. JavaWeb之XML详解

    XML语言 什么是XML? XML是指可扩展标记语言(eXtensible Markup Language),它是一种标记语言,很类似HTML.它被设计的宗旨是传输数据,而非显示数据. XML标签没有 ...

  7. Ajax.ActionLink参数详解

    该语法会生成一个a标签,点击a标签会执行一个Ajax请求. 有12个方法重载,下面详解方法中的各项参数: 参数一:linkText string类型 说明:链接显示的文字内容 参数二:actionNa ...

  8. Ajax.BeginForm参数详解

    在Asp.Net的MVC中的语法,在Razor页面中使用,替代JQuery的Ajax使用,方便快捷. 使用Ajax.BeginForm方法会生成一个form表单,最后以Ajax的方式提交表单数据:需要 ...

  9. 【JAVA与XML、dtd约束、Schema约束】

    一.XML. (1)XML:Extensible Markup Language (2)XML是一种标记语言. (3)XML的设计宗旨是传输数据,而不是显示数据. (4)XML标签没有被预定义,即使用 ...

随机推荐

  1. 使用 pm2-web 监控 pm2 服务运行状态

    pm2-web 是一款 pm2 服务状态监控程序,基于 web . 安装 $ npm install -g pm2-web 运行(默认是在8080端口) $ pm2-web 配置 pm2-web 将会 ...

  2. EntityFramework:值语义的实体如何修改?

    背景 现在很流行值对象,值对象有如下特点:开发简单.使用简单和多线程安全.我试着让 EntityFramework 中的实体保持值语义,这样的话,对值语义实体的修改就应当等于“整体替换”,好像有点问题 ...

  3. [Android 新特性] 改进明显 Android 4.4系统新特性解析

    Android 4.3发布半年之后,Android 4.4随着新一代Nexus5一起出现在了用户的面前,命名为从之前的Jelly Bean(果冻豆)换成了KitKat(奇巧).这个新系统究竟都有怎样的 ...

  4. Spring核心之IoC——依赖注入

    在J2EE开发平台中,Spring是一种优秀的轻量级企业应用解决方案.Spring倡导一切从实际出发,它的核心技术就是IOC(控制反转)和AOP(面向切面编程)技术.本文用的Spring版本为spri ...

  5. 挑战黑客极限:Pwn2Own 2015成史上“最难”黑客大赛

    Pwn2Own是全球最著名.奖金最丰厚的黑客大赛,由美国五角大楼入侵防护系统供应商TippingPoint赞助.近日Pwn2Own 2015公布全新的比赛规则,本届赛事难度超高.史无前例,包括VUPE ...

  6. idea maven 报-source 1.5 中不支持 diamond 运算符

    需要修改 project setting 中的

  7. 解决Ubuntu Ping网关Destination Host Unreachable错误

    ifconfig 检查了配置,没问题,是ok的, 检查了防火墙,是关闭的,邪乎了,是什么问题呢 各种尝试,最后,将 ip 搞成自动获取就 可以ping通了,但为啥手动设置就不行呢? 最后看了这个朋友的 ...

  8. T_SQL的 FOR XML PATH 用法

    T_SQL的 FOR XML PATH FOR XML PATH 有的人可能知道有的人可能不知道,其实它就是将查询结果集以XML形式展现,有了它我们可以简化我们的查询语句实现一些以前可能需要借助函数活 ...

  9. 最短路+状态压缩dp(旅行商问题)hdu-4568-Hunter

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4568 题目大意: 给一个矩阵 n*m (n m<=200),方格里如果是0~9表示通过它时要花 ...

  10. python 网络请求类库 requests 使用

    python 网络请求类库 requests 使用 requests是 为python封装的强大 REST 操作类库 githubhttps://github.com/kennethreitz/req ...