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 标准标记为过时了!简直太可怕了。