分析复杂的C语言声明

    技术2022-06-13  76


    目录


            引言

            基本的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版·新版)

     

     


    最新回复(0)