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


    本文已迁移至:

    http://www.danfengcao.info/c/c++/2014/02/25/howto-understand-complicated-declaration-of-c.html

    C语言中有时会出现复杂的声明,比如

    char * const * (*next) (); //这是个什么东东?

    在讲复杂声明的分析方法前,先来个补充点。


    C语言变量的声明始终贯彻两点

    1.声明和使用的语法尽量保持一致

    例如:

    #include <iostream>
    using namespace std;
    
    double (*fun)(double);       //声明一个函数指针
    
    int main(){
       fun=sin;
       doube reslut=(*fun)(0.5);//使用这个函数指针
       ...  
    }

    2.声明语句不是的阅读不是按照从左往右的阅读顺序,而是要根据各个符号的优先级进行阅读

    这点非常重要!先列出C语言声明的优先级规则,再举个例子就能掌握求解方法了。

    C语言声明的优先级规则

    A 声明从它的名字开始读取,然后按照优先级顺序依次读取;

    B 优先级从高到低依次是:

        B.1 声明中被括号括起来的那部分;

        B.2 后缀操作符:

              括号()表示这是一个函数,而

              放括号[]表示这是一个数组;

        B.3 前缀操作符:星号*表示这是一个“指向...的指针”;

    C 如果const和(或)volatile关键字的后面紧跟类型说明符(如int,long等),那么它作用于类型说明符。在其他情况下,它作用于关键字左边紧邻的指针星号。

     

    需要强调的一个重要注意点是,对于优先级: () > [] > *

    举例,用优先级规则分析C语言声明一例:

    char * const * (*next) ();

    按照规则解读 char * const * (*next) ();

    首先,(*next) 表示next是一个指针,它指向某个东东;

    根据B.2和最右边的括号,next指向一个函数;

    根据B.3,第二个星号表示,该函数返回一个指针;

    char * const是函数返回的指针所指向的类型;

    char* 是字符指针,const修饰左边的星号,即字符指针是常量的,该指针不可修改(该指针指向的字符内容是可修改的);

    综合地表述为,next是一个指针,它指向一个函数,该函数返回一个指针,该指针指向一个类型为char的常量指针。

    还是不明白?再往下看就明白了!

    #---------------------------------------------------------------------------------#

    总结一下,分析复杂的C语言声明,要采用"由内而外,层层剥离”的策略。

    从哪里开始剥?从语句的最左边的标志符开始剥(上例为从next开始)。

    往哪个方向剥?依照C语言的优先级规则一层层剥。

    #---------------------------------------------------------------------------------#

    再举一例作详细说明:

    char *(* c[10]) (int **p);

    第一步,char *(* c[10]) (int **p);  最左边的标志符是c,表示"c是一个什么东东";

    第二步,char *(*  [10]) (int **p);  和[10]结合,表示"c是一个长度为10的数组";

    第三步,char *(*        ) (int **p);  和*结合,表示"这个数组存放着指针";

    第四步,char *             (int **p);  和(int **p)结合,表示"这个指针指向一个函数,函数的参数是二维指针";

    第五步,char *                         ;  和 * 结合,表示"这个函数返回一个指针";

    第六步,char              ; 这个指针指向一个字符;

    把上面六步串起来,读作: c是一个数组[0..9],它存放着指针,指针指向的函数参数是一个二维指针返回值是指向字符的指针。完工!

    #---------------------------------------------------------------------------------#

    注1: 这个方法若理解了,什么指针数组和数组指针、指针函数和函数指针等等之类的区别都是小菜一碟了。

    注2: 合法的声明中存在限制条件。如函数的返回值不能是一个函数,也不能是一个数组,所以像function()()和function()[]是非法的,不能出现。数组里面能存函数指针,但不能存函数,像int (* function[])()是合法的,function[]()则是非法的。

    #---------------------------------------------------------------------------------#

    参考文献

    《C专家编程》, Peter Van Der Linden 著, 徐波 译  

  • 相关阅读:
    Rotate Always Encrypted keys using SQL Server Management Studio
    ABP Web Application Development Tutorial Part 1: Creating the Server Side
    Fiddler 2 Wipes My Internet Explorer Proxy Settings
    API设计浅析
    泛型的实现浅谈
    搜狗workflow异步调度框架
    MQTT 和 CoAP
    深入理解左值、右值
    C++ 头文件接口设计浅谈
    Windows无Internet但能正常上网的问题
  • 原文地址:https://www.cnblogs.com/dfcao/p/expertCprogramming_chap3_3-3.html
Copyright © 2020-2023  润新知