分析复杂的C语言声明


目录


        引言

        基本的C语言声明

        较复杂的C语言声明

        没有最复杂,只有更复杂

        C语言声明的分析法则

        分析法则的运用

        结束语

        参考文献


引言

        C语言常常因为声明的语法而收到人们的批评,特别是涉及到函数指针的用法。对于简单的情况,C语言的做法是很有效的,但是,如果情况比较复杂,则容易让人混淆,原因在于,C语言的声明不能从左至右阅读,而且使用了太多的圆括号。

        本文旨在总结自己在分析C语言声明方面的学习心得,并与大家交流C语言声明的一般分析方法,希望能够帮助大家攻克理解C语言声明的难关。本文首先从简到繁地列出C语言中的各种声明,然后给出C语言声明的分析法则,最后通过一些实例讲解该分析法则的实际运用。


基本的C语言声明


        1、int a;                                                                         

              a为常规变量,该变量具有int类型

        2、int a[2];                                                                                  

              a为数组,该数组包含2个int变量

        3、int *p;     

              p为指针,该指针指向一个int变量

        4、int f();      

              f为函数,该函数无参数且返回一个int变量

        5、struct person { char *name, int height, int weight; };

              struct person a;     

              a为结构体变量

        6、union bits32
              {
                  int whole;
                  struct { char c0, c1, c2, c3; } byte;

              };

               union bits32 a;          

               a为联合体变量

         7、enum fruit {apple=8, pear, orange=12, banana};

               enum fruit a;                        

               a为枚举变量


较复杂的C语言声明


        1、int *a[2];                                                                                          

              a为数组,该数组包含2个指向int的指针

               int (*a)[2];                                                                                        

              a为指针,该指针指向一个数组,该数组包含2个int

        2、const int *p;                                                                                    

              p为指针,该指针指向一个只读int

              int const *p;                                                                                    

              同上

              int * const p;                                                                                   

              p为只读指针,该指针指向一个int

              const int * const p;                                                                        

              p为只读指针,该指针指向一个只读int

              int const * const p;                                                                        

              同上

        3、int **p;                                                                                             

              p为指针,该指针指向一个对象,该对象为指向int的指针

              int * const *p;                                                                                 

              p为指针,该指针指向一个对象,该对象为指向int的只读指针

        4、int *f();                                                                                             

              f为函数,该函数无参数且返回一个指向int的指针

              int (*f)();                                                                                           

              f为指针,该指针指向一个函数,该函数无参数且返回一个int


没有最复杂,只有更复杂


        下面的声明,你能读懂几个?

        1、int (*func)(int *p, int (*f)(int*));

        2、int (*func[5])(int *p);

        3、int (*(*func)[5])(int *p);

        4、int (*(*func)(int *p))[5];

        5、int func()();

        6、int func()[5];

        7、int func[5]();


C语言声明的分析法则


        C语言声明的分析法则,可以表达为如下几个步骤:

        1、从左到右找到第1个标识符tag

        2、查看tag右边的下一个符号:
              如果是“[”,即形如“tag[N]”,则tag为一个数组;(其中,N为数组大小)
              如果是“(”,即形如“tag(…)”,则tag为一个函数。(其中,…为函数参数)
              以上两种情况,跳到4

        3、查看tag左边的上 一个符号:
              如果是
“*”,即形如“*tag”,则tag为一个指针
              如果是类型名称,如“int tag”,则tag为一个常规变量,跳到5

        4、判断tag的 性质:
              如果是
数组,在tag的声明字符串中,用“tag1”替换“tag[N]”,则数组tag中的元素为tag1;
              如果是函数,在tag的声明字符串中,用“tag1”替换“tag(…)”,则函数tag的返回值为tag1;
              如果是指针,在tag的声明字符串中,用“tag1”替换“*tag”(或者更常见的“(*tag)”),则指针tag所指向的对象为tag1
            (注意:若tag1的声明较复杂,则跳到2分析tag1

                          
若被tag1替换的部分或tag1本身为函数,且其中的某个参数par的声明较复杂,则跳到2分析par
             

        5、结束


分析法则的运用


        在“没有最复杂,只有更复杂”一节,我们列出了一些非常复杂的C语言声明,其中不少声明源自网上一些朋友的文章中的例子。那些声明尽管在实际中很少遇到,但对它们的研究非常有助于我们掌握C语言声明的分析方法。对于那些复杂声明,如果在那时你觉得束手无策、摸不着边,那么此刻在给出了“C语言声明的分析法则”之后,你就应该能够有章可循、从容不迫了。

        下面我们将运用“C语言声明的分析法则”,逐一对那些复杂的C语言声明进行分析理解:

        1、int (*func)(int *p, int (*f)(int*));

        标识符:func
        右边:( ,左边:*
        因此func是一个指针,用a替换(*func),则func指向a对象
        a的声明:int a(int *p, int (*f)(int *));较简单
        a为一个函数,该函数的第2个参数f较复杂,分析标识符f
        使用分析法则,得出f为一个函数指针
        结论:func是一个函数指针,它指向的函数返回int,且以p和f为参数。其中p为int指针;f为另一个函数指针,该函数返回int,以一个int指针为参数。

        2、int (*func[5])(int *p);

        标识符:func
        右边:[
        因此func是一个数组,用a替换func[5],则func中有5个a
        a的声明:int (*a)(int *p);较复杂,分析标识符a
        使用分析法则,得出a为一个函数指针
        结论:func是一个数组,其中有5个元素,每个元素都是函数指针。函数指针指向的函数返回int,且以一个int指针p为参数。

        3、int (*(*func)[5])(int *p);

        结论:func是一个数组指针,它指向的数组具有5个元素,每个元素都是函数指针。该函数指针指向的函数返回int,且以一个int指针p为参数。

        4、int (*(*func)(int *p))[5];

        结论:func是一个函数指针,它指向的函数以int指针为参数,且返回一个数组指针。该数组指针指向的数组具有5个元素,每个元素都是int。

        5、int func()();

        func是一个函数,它返回一个函数。返回的函数无参数,且返回一个int

        非法:在C语言中,函数的返回值不能是一个函数!

        6、int func()[5];

        func是一个函数,它返回一个具有5个int的数组

        非法:在C语言中,函数的返回值不能是一个数组!

        7、int func[5]();

        func是一个具有5个元素的数组,每个元素都是一个函数,该函数无参数,且返回一个int

        非法:在C语言中,数组里面不能有函数!

        由上面的分析实例可以看出,不管是合法的C语言声明,还是非法的C语言声明,其分析法则都是一致的。非法的C语言声明只是不满足语法要求而已。C语法对声明的合法性有限制,但C语言声明的分析法则却没有限制。由此可见,“C语言声明的分析法则”一节中给出的分析法则是一种通用法则,对于C语言中的任何声明,不管是简单的C语言声明(大家对于简单的C语言声明多是根据平时的记忆积累来判断的,不妨用我们的分析规则来分析理解一下,定能加深你对一些常见简单的C语言声明的认识),还是复杂的C语言声明,都可以用该法则来进行分析理解。当然,只有对合法的C语言声明进行分析才是有意义的:-)


结束语


        通过上面的讲解,我相信大家对C语言声明一定有了更深的认识,对于分析简单或复杂的C语言声明也一定有了更多的把握。

        学习贵在总结、分享与交流。这篇文章是我学习C语言声明分析的阶段性总结;如果本文能够给大家带来启发和帮助,那我花一下午的时间来打字和排版就更值得了;当然,本人能力有限,如果有阐述不清、描述不当甚至观点有误的地方,还请大家给予批评指正。


参考文献


《C专家编程》
《C程序设计语言》(第2版·新版)

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值