Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c编译器如何解释同一语句中声明的函数和变量?_C_Pointers_Kernighan And Ritchie - Fatal编程技术网

c编译器如何解释同一语句中声明的函数和变量?

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)的

我在K&R中遇到过一个声明,在“指针”一章中,函数和变量一起声明:

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)。而
    double atof()
    表示接受任何参数的函数。根据C17 6.11.6,这是过时的样式
  • 在一行中写入多个声明。不要写像
    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