1.C语言声明的单独语法成份
    声明器是C语言声明的非常重要成份,他是所有声明的核心内容,简单的说:声明器就是标识符以及与它组合在一起的任何指针、函数括号、数组下表等,为了方便起见这里进行分类表示。
  1)指针
    (1)*
    (2)* const
    (3)* volatile
    (4)* const volatile
    (5)* volatile const
  2)直接声明器
    (1)标识符
    (2)标识符[下表]
    (3)标识符(参数)
    (4)(声明器)
  3)初始化内容
    (1)= 初始值
    C语言中的完整声明包括的内容如下:
  1)类型说明符:包括存储类型和类型限定符
  2)声明器(见上面)
  3)更多的声明器
  4)分号
    注意:不是上面的所有组合都是合法的,如:你不能像这样声明foo()()、foo()[]。

2.优先级规则
    上面说明C语言中声明的各个组成部分,要理解一个声明必须要动的其中的优先级规则,可以简洁的以下面形式来直观的反应这个规则:
  A 声明从他的名字开始读取,然后按照优先级顺序依次读取
  B 优先级从高到低依次是:
    (1)声明中被括号括起来的部分
    (2)后缀操作符:括号()表示这是个函数,而方括号[]表示这是一个数组
    (3)前缀操作符:星号*表示"指向...的指针"
  C 如果const和(或)volatile关键字的后面紧跟类型说明符(如:int, long等),那么它作用于类型说明符;否则其它情况下作用于它左边紧邻的指针星号。
    const char *p; /* 常量指针 */
    char const *p; /* 同上 */
    char * const p;     /* 指针常量 */

3. 举例说明
    (1)用优先级规则分析C语言声明一例:
    char * const *(*next)();

下面使用优先级规则解决这个声明:
    A 首先,看变量名"next",并注意到它直接被括号所扩住
    B.1 所以先把括号里得东西作为一个整体,得出"next是一个指向...的指针"
    B 然后考虑括号外面的东西,在星号前缀和括号后缀之间做出选择
    B.2 该规则告诉我们优先级较高的是右边的函数括号,所以得出“next是一个函数指针,指向一个返回...的函数”
    B.3 然后,处理前缀“*”,得出指针所指的内容
    C 最后把“char * const”解释为指向字符的常量指针

上述的分析结果可以概括为:这个声明表示next是一个指针,它指向一个函数,该函数返回一个指针,该指针指向一个类型为char的常量指针。

(2)分析C语言声明二例:
    int *(*p[])();

A 首先,看变量名"p",并注意到它直接被括号所扩住
    B.1 所以先把括号里得东西作为一个整体,得出"p是一个指向...的指针数组"
    B 然后考虑括号外面的东西,在星号前缀和括号后缀之间做出选择
    B.2 该规则告诉我们优先级较高的是右边的函数括号,所以得出“p是一个指向函数指针数组的指针,数组的每一个元素返回值是...的函数”
    B.3 然后,处理括号外的前缀“*”,得出指针所指的内容
    C 最后把“int *”解释为指向整形的指针

上述的分析结果可以概括为:这个声明表示p是一个指针,它指向一个函数指针数组,数组中每一个元素的形参为空,返回类型为指向一个类型为int指针。

(3)分析C语言声明三例:
    void (*signal(int sig,void(*func)(int)))(int);

乍一看,这是一个很吓人的声明,不过掌握了前面的优先级规则,再分析这个声明就简单的多了:
    A 首先,看变量名"signal",并注意到它直接被括号所扩住
    B.1 所以先把括号里得东西作为一个整体,得出"signal是一个指向...的函数指针,有形参有返回值,返回值是一个指向...的指针"
    B 然后考虑括号外面的东西,在星号前缀和括号后缀之间做出选择,显然括号外面的东西就是signal的返回值
    B.2 该规则告诉我们优先级较高的是右边的函数括号,所以得出“signal的返回值也是一个指向...的函数指针”
    B.3 然后,括号外没有"*"前缀
    C 没有符合的情况

上述的分析结果可以概括为:这个声明表示signal是一个指针,它指向一个函数,该函数的形参为int和一个函数指针void(*func)(),返回类型也为一个函数指针,该函数的形参int,返回值为void。
    掌握了这个方法,碰到再复杂的C声明语句都能轻松搞定了。

C语言声明解析方法的更多相关文章

  1. [C语言]声明解析器cdecl修改版

    一.写在前面 K&R曾经在书中承认,"C语言声明的语法有时会带来严重的问题.".由于历史原因(BCPL语言只有唯一一个类型——二进制字),C语言声明的语法在各种合理的组合下 ...

  2. c语言复杂声明解析

    这是个好东西,接触c语言好几年了,第一次看到这东西,惊喜万分. 先提供个分析案例,以后看方便 vector <int> * (*seq_array[]) (int )={func1,fun ...

  3. 如何解析复杂的C语言声明

    C语言中有时会出现复杂的声明,比如   char * const * (*next) (); //这是个什么东东?   在讲复杂声明的分析方法前,先来个补充点.   C语言变量的声明始终贯彻两点 :  ...

  4. 16.C语言中数据类型的本质含义是:表示一个内存格子的长度和解析方法。

    数据类型决定长度的含义:我们一个内存地址(0x30000000),本来这个地址只代表1个字节的长度,但是实际上我们可以通过给他一个类型(int),让他有了长度(4),这样这个代表内存地址的数字(0x3 ...

  5. Lambda语言篇 —— lambda, 方法引用, 目标类型和默认方法

    本文介绍了Java SE 8中新引入的lambda语言特性以及这些特性背后的设计思想.这些特性包括: lambda表达式(又被成为"闭包"或"匿名方法") 方法 ...

  6. C语言声明语句

    设计理念: C语言的一个设计理念就是声明变量和使用变量的形式应该是一致的 优点:声明变量和使用变量时的运算符优先级是相同的 缺点:运算符的优先级是C语言过度解析的部分之一 术语: 变量声明中使用到的符 ...

  7. Go语言 - 结构体 | 方法

    自定义类型和类型别名 自定义类型 在Go语言中有一些基本的数据类型,如string.整型.浮点型.布尔等数据类型, Go语言中可以使用type关键字来定义自定义类型. 自定义类型是定义了一个全新的类型 ...

  8. 如何读懂复杂的C语言声明

    本文已迁移至: http://www.danfengcao.info/c/c++/2014/02/25/howto-understand-complicated-declaration-of-c.ht ...

  9. 八、Android学习第七天——XML文件解析方法(转)

    (转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 八.Android学习第七天——XML文件解析方法 XML文件:exten ...

随机推荐

  1. WebRTC Demo - getUserMedia()

    WebRTC介绍 WebRTC提供三类API: MediaStream,即getUserMedia RTCPeerConnection RTCDataChannel getUserMedia已经由Ch ...

  2. cmake 学习笔记(四)

    接前面的一二三,学习一下 CMakeCache.txt 相关的东西. CMakeCache.txt 可以将其想象成一个配置文件(在Unix环境下,我们可以认为它等价于传递给configure的参数). ...

  3. STL之vector详解

    一.vector容器的自增长 首先,我们知道vector容器是由数组做出来的:它具备了数组的优缺点. 数组的优点: 操作数据,读取速度很快,因为有下标: 数组的缺点: 分配之后不能在改变大小: #in ...

  4. css基础(二)

    一.元素内容的字体属性 1.font-family   字体名称,例如:宋体,新罗马字体等 注意:1.不能使用偏僻的字体,要使用安全字体,如:arial;verdana;times new roman ...

  5. 非root不能gdb attach的限制

    Could not attach to process.  If your uid matches the uid of the targetprocess, check the setting of ...

  6. poemel 端口作用

    clientPort 用于connetor组件启动时候,监听的调用,用于客户端连接 port用于服务器间通信,即rpc调用时候使用,在remote组件启动时候,生成remote,即gateway实例, ...

  7. java数组中的三种排序方法中的冒泡排序方法

    我记得我大学学java的时候,怎么就是搞不明白这三种排序方法,也一直不会,现在我有发过来学习下这三种方法并记录下来. 首先说说冒泡排序方法:冒泡排序方法就是把数组中的每一个元素进行比较,如果第i个元素 ...

  8. javascript 简单实现对两个数组相似度的检验

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. Week2(9月16日):动手做个简单的例子

    Part I:提问  =========================== 1.什么是ASP.NET MVC? 2.MVC的英文? 3.什么是模型? 4.什么是控制器? 5.什么是视图? 6.ASP ...

  10. ASP.NET MVC 5 学习教程:数据迁移之添加字段

    原文 ASP.NET MVC 5 学习教程:数据迁移之添加字段 起飞网 ASP.NET MVC 5 学习教程目录: 添加控制器 添加视图 修改视图和布局页 控制器传递数据给视图 添加模型 创建连接字符 ...