c编译器如何解释同一语句中声明的函数和变量?
我在K&R中遇到过一个声明,在“指针”一章中,函数和变量一起声明:c编译器如何解释同一语句中声明的函数和变量?,c,pointers,kernighan-and-ritchie,C,Pointers,Kernighan And Ritchie,我在K&R中遇到过一个声明,在“指针”一章中,函数和变量一起声明: double atof(), *dp; C编译器如何处理上述声明?在C中,逗号可以用作运算符或分隔符。在您的例子中,它起到分隔符的作用 如果您仔细阅读在线提供的C语法,您将发现逗号作为分隔符的许多用法。 其中一种用途如下: init_declarator_list : init_declarator | init_declarator_list ',' init_declarator 声明(C17 6.7)的
double atof(), *dp;
C编译器如何处理上述声明?在C中,逗号可以用作运算符或分隔符。在您的例子中,它起到分隔符的作用 如果您仔细阅读在线提供的C语法,您将发现逗号作为分隔符的许多用法。 其中一种用途如下:
init_declarator_list
: init_declarator
| init_declarator_list ',' init_declarator
声明(C17 6.7)的语法为: 其中一种声明说明符是类型说明符,在本例中为
double
进一步深入到init声明器列表中,会得到init声明器,可以选择几个以逗号分隔的声明器:
init-declarator-list:
init-declarator
init-declarator-list , init-declarator
init_declarator依次给出declarator,该declarator具有以下语法(C17 6.7.6):
在本例中,atof()
和dp
是直接声明符,其中dp
具有可选的指针语法
这意味着atof()
结束一个返回double
和*dp
指向double
的指针的函数
(如果你想深入研究上述原始语法,标准的附录A是很有帮助的。没有理智的人会在不查的情况下记住这些东西。)
但真的没有理由去思考像这样写得很糟糕的代码。以下是公认的不良做法:
- 在文件范围内,将函数声明作为自己的一行写入其他任何位置
- 编写没有原型格式的函数声明。标准C 7.22.1.1中
的正确原型是atof
double-atof(const-char*nptr)代码>。而
表示接受任何参数的函数。根据C17 6.11.6,这是过时的样式double atof()
- 在一行中写入多个声明。不要写像
double d,*dp代码>,写
双d;双*dp代码>。众所周知,前者由于意外声明了错误的类型而导致错误。另外,如果您总是拆分声明,则无需考虑编写
样式还是double*dp
样式更为正确double*dp
小结:不要读上世纪70年代过时的编程书籍。试图对C90进行K&R更新是草率的,本书第二版的很多内容都没有随着1989年的变化而更新。例如,C906.9.4中已经存在过时的样式。因此,这本书包含的实践在1989年已经被C标准标记为过时!简直可怕。轻松自如。这里的实际问题是什么?您显然已经很清楚,它将声明一个函数和一个变量。那么你的问题是什么?你对此有什么怀疑?您是否正在考虑其他结果?逗号分隔要声明的内容。如果编译器看到一个逗号结束所声明的内容,它将查找另一个逗号。如果它看到一个分号,它就知道这个语句已经结束了。只是不要读K&R,它已经非常过时了,并且教你糟糕的做法。你从来没有理由写这样的垃圾代码。atof的正确类型是
double-atof(const-char*str)代码>,在文件范围内声明为原型。您是否真的想知道在这种情况下,dp
是什么类型?(这与您刚刚编写的double*dp;
相同)
init-declarator-list:
init-declarator
init-declarator-list , init-declarator
declarator:
pointer(opt) direct-declarator