c编译器如何解释在同一语句中声明函数和变量?
How does c compiler interpret declaring function and variable in the same statement?
我看到了 K&R 中的一个声明,其中在 'Pointers' 章节中一起声明了一个函数和一个变量:
double atof(), *dp;
C 编译器如何处理上述声明?
在C语言中,逗号可以用作运算符或分隔符。在您的情况下,它起到分隔符的作用。
如果您仔细阅读在线提供的 C 语法 here,您会发现许多使用逗号作为分隔符的方法。
其中一种用途如下:
init_declarator_list
: init_declarator
| init_declarator_list ',' init_declarator
声明的语法 (C17 6.7) 是:
declaration:
declaration-specifiers init-declarator-list(opt) ;
声明说明符的一种情况是类型说明符,在这种情况下double
.
进一步挖掘 init-declarator-list 给出 init-declarator,可选的几个用逗号分隔:
init-declarator-list:
init-declarator
init-declarator-list , init-declarator
init_declarator 依次给出 声明符,其语法为 (C17 6.7.6):
declarator:
pointer(opt) direct-declarator
在示例中,atof()
和 dp
是 直接声明符 ,其中 dp
具有可选的指针语法。
这意味着 atof()
结束一个返回 double
和 *dp
指向 double
.
的函数
(如果你想深入了解上面的原始语法,标准的附件 A 会很有帮助。没有一个理智的人会在不查找的情况下记住这样的事情。)
但是真的没有理由去思考这样写得糟糕的代码。以下是公认的不良做法:
- 在其他任何地方编写函数声明,但在文件范围内作为它自己的一行。
- 编写没有原型格式的函数声明。标准 C 7.22.1.1 中
atof
的正确原型是 double atof(const char *nptr);
。而 double atof()
表示接受任何参数的函数。根据 C17 6.11.6,这是过时的样式。
- 在一行中写入多个声明。不要写
double d, *dp;
之类的东西,写double d; double* dp;
。众所周知,前者会因为不小心声明了错误的类型而导致错误。作为奖励,如果您总是拆分声明,则不必考虑编写 double* dp
样式还是 double *dp
样式更正确。
总结:不要阅读 70 年代的过时编程书籍。尝试对 C90 进行 K&R 更新是草率的,并且该书的许多第 2 版都没有跟上 1989 年的变化。例如,过时的样式已经存在于 C90 6.9.4 中。所以这本书包含的实践在 1989 年已经被 C 标准标记为过时了!简直太可怕了。
我看到了 K&R 中的一个声明,其中在 'Pointers' 章节中一起声明了一个函数和一个变量:
double atof(), *dp;
C 编译器如何处理上述声明?
在C语言中,逗号可以用作运算符或分隔符。在您的情况下,它起到分隔符的作用。
如果您仔细阅读在线提供的 C 语法 here,您会发现许多使用逗号作为分隔符的方法。 其中一种用途如下:
init_declarator_list
: init_declarator
| init_declarator_list ',' init_declarator
声明的语法 (C17 6.7) 是:
declaration:
declaration-specifiers init-declarator-list(opt) ;
声明说明符的一种情况是类型说明符,在这种情况下double
.
进一步挖掘 init-declarator-list 给出 init-declarator,可选的几个用逗号分隔:
init-declarator-list:
init-declarator
init-declarator-list , init-declarator
init_declarator 依次给出 声明符,其语法为 (C17 6.7.6):
declarator:
pointer(opt) direct-declarator
在示例中,atof()
和 dp
是 直接声明符 ,其中 dp
具有可选的指针语法。
这意味着 atof()
结束一个返回 double
和 *dp
指向 double
.
(如果你想深入了解上面的原始语法,标准的附件 A 会很有帮助。没有一个理智的人会在不查找的情况下记住这样的事情。)
但是真的没有理由去思考这样写得糟糕的代码。以下是公认的不良做法:
- 在其他任何地方编写函数声明,但在文件范围内作为它自己的一行。
- 编写没有原型格式的函数声明。标准 C 7.22.1.1 中
atof
的正确原型是double atof(const char *nptr);
。而double atof()
表示接受任何参数的函数。根据 C17 6.11.6,这是过时的样式。 - 在一行中写入多个声明。不要写
double d, *dp;
之类的东西,写double d; double* dp;
。众所周知,前者会因为不小心声明了错误的类型而导致错误。作为奖励,如果您总是拆分声明,则不必考虑编写double* dp
样式还是double *dp
样式更正确。
总结:不要阅读 70 年代的过时编程书籍。尝试对 C90 进行 K&R 更新是草率的,并且该书的许多第 2 版都没有跟上 1989 年的变化。例如,过时的样式已经存在于 C90 6.9.4 中。所以这本书包含的实践在 1989 年已经被 C 标准标记为过时了!简直太可怕了。