zoukankan      html  css  js  c++  java
  • C语言声明解析方法

    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声明语句都能轻松搞定了。

      

  • 相关阅读:
    MySQL 之 Metadata Locking 研究
    Spring, MyBatis 多数据源的配置和管理
    ThreadLocal 源码剖析
    Java多线程中的死锁问题
    Java并发基础框架AbstractQueuedSynchronizer初探(ReentrantLock的实现分析)
    PriorityQueue和Queue的一种变体的实现
    被我们忽略的HttpSession线程安全问题
    Java并发之原子变量和原子引用与volatile
    使用Java实现单线程模式
    这些年无处安放的博客
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3153180.html
Copyright © 2011-2022 走看看