C:为什么额外的分号可以?

C:为什么额外的分号可以?,c,C,有人能告诉我为什么第8行仍然可以用多个分号吗;;;;;都是空话。它们在C中是允许的;;;;;都是空话。它们在C中是允许的。空语句在C中是合法的;是语句终止符,多个;在语法上是有效的。有时这甚至是有用的:例如for;;{/*代码在这里*/}习惯用法 尽管某些编译器会在适当的情况下向您发出警告 请注意,至少在概念上,过剩;在该行中,不属于if块。空语句在C中是合法的;是语句终止符,多个;在语法上是有效的。有时这甚至是有用的:例如for;;{/*代码在这里*/}习惯用法 尽管某些编译器会在适当的情况下

有人能告诉我为什么第8行仍然可以用多个分号吗;;;;;都是空话。它们在C中是允许的;;;;;都是空话。它们在C中是允许的。

空语句在C中是合法的;是语句终止符,多个;在语法上是有效的。有时这甚至是有用的:例如for;;{/*代码在这里*/}习惯用法

尽管某些编译器会在适当的情况下向您发出警告

请注意,至少在概念上,过剩;在该行中,不属于if块。

空语句在C中是合法的;是语句终止符,多个;在语法上是有效的。有时这甚至是有用的:例如for;;{/*代码在这里*/}习惯用法

尽管某些编译器会在适当的情况下向您发出警告

请注意,至少在概念上,过剩;该行中的语句不属于if块。

它是printf语句之后的null语句。允许有多个分号

C11,§6.8.3,4

仅由分号组成的null语句不执行 操作

这是一个空语句,在printf语句之后。允许有多个分号

C11,§6.8.3,4

仅由分号组成的null语句不执行 操作


您的程序在主函数的末尾只有一系列空语句。它被解析为:

#include <stdio.h>

int main() {
    int a = -1, b = -10, c = 5;
    if (a > b)
        printf("Hello World");
    else
        printf("Get out World");;;;;;
}

注意,int main应该写为int mainvoid,它应该返回一个int值,例如0。C99使该返回值为0;隐式,但它被认为是不好的样式,省略它确实不太便于移植。

您的程序只是在主函数的末尾有一系列空语句。它被解析为:

#include <stdio.h>

int main() {
    int a = -1, b = -10, c = 5;
    if (a > b)
        printf("Hello World");
    else
        printf("Get out World");;;;;;
}

注意,int main应该写为int mainvoid,它应该返回一个int值,例如0。C99使该返回值为0;隐式的,但它被认为是不好的风格,省略它确实不太便于携带。

正如我们所知,分号;用作语句终止符。在第8行中,第一个分号终止else下的语句,下一个分号终止空语句,依此类推;用作语句终止符。在第8行中,第一个分号终止else下的语句,下一个分号终止空语句,依此类推。

额外的分号通常不合适

例如,稍微更改代码:

#include <stdio.h>

int main() {
    int a = -1, b = -10, c = 5;

    if (a > b)
        printf("Hello World");
    else
        printf("Get out World");
    ;
    ;
    ;
    ;
    ;
}

一般来说,额外的分号是不合适的

例如,稍微更改代码:

#include <stdio.h>

int main() {
    int a = -1, b = -10, c = 5;

    if (a > b)
        printf("Hello World");
    else
        printf("Get out World");
    ;
    ;
    ;
    ;
    ;
}
那么,;C中的分号是语句终止符,这意味着您不能将它放在您喜欢的地方,只能放在语句的末尾

不执行任何操作的null语句在C中是有效的,它允许您按照发布的语句编写内容,以及以下内容:

   ...

   int done = 0;

   ...

   while ( !done );
   {
       ...

       done = 1;
   }

   ...
应该更明显,因为单个分号太小,无法在快速读取中跳过:

while((data = do_read(...)) != NULL); /* skip input until EOF */
这看起来更好,因为你永远不会认为下一行在循环中

顺便说一句,如果你写了这样的东西:

while((data = do_read(...)) != NULL) continue;
在这里,由于编译器出现语法错误,您无法拥有一个好的C程序,因此您无法进一步分析编译器试图恢复并继续解析超过该点的代码,但您可能会出现新条件引起的新错误,或伪错误;C中的分号是语句终止符,这意味着您不能将它放在您喜欢的地方,只能放在语句的末尾

不执行任何操作的null语句在C中是有效的,它允许您按照发布的语句编写内容,以及以下内容:

   ...

   int done = 0;

   ...

   while ( !done );
   {
       ...

       done = 1;
   }

   ...
应该更明显,因为单个分号太小,无法在快速读取中跳过:

while((data = do_read(...)) != NULL); /* skip input until EOF */
这看起来更好,因为你永远不会认为下一行在循环中

顺便说一句,如果你写了这样的东西:

while((data = do_read(...)) != NULL) continue;

在这里,由于编译器出现语法错误,您不能拥有一个好的C程序,因此您无法进一步分析编译器试图恢复并继续解析超过该点的代码,但您可能会有新的错误源于新的条件,或者假错误

因为-1大于-10?你能解释一下你所说的仍然有效吗?我的意思是有不止一个分号。实际输出是什么?你的预期产出是多少。哪一行是第8行?在控制语句中省略花括号有些危险。特别是对于经常使用Python的人。因为-1大于-10?你能解释一下你所说的“仍然有效”是什么意思吗?我的意思是有不止一个分号。实际输出是什么?你的预期产出是多少。哪一行是第8行?在控制语句中省略花括号有些危险。特别是对于经常使用Python的人。有没有类似的情况?我不明白你的问题。空语句在任何接受语句的地方都被接受
有这样的情况吗?我不明白你的问题。空语句在任何接受语句的地方都被接受。我曾经使用过的Sun Solaris编译器在这方面发出了一个错误,非常恼人。但这是90年代后期的C++编译器。128位长的double弥补了它的不足-我曾经使用过的一个Sun Solaris编译器在这个问题上发出了一个错误,这非常恼人。但这是90年代后期的C++编译器。128位长的double弥补了它的不足-int mainvoid是一个错误。。。请更正你的答案。当前的方法是省略main函数的main int,或者将它们放在int Mint INARC中,const char **ARGV},但是不要放入错误的int int MaViObj.Myst:恐怕你错了:你的注释对于C++是正确的,但是对于C,因为问题被标记了。5.1.2.2.1程序启动程序启动时调用的函数名为main。实现没有声明此函数的原型。应使用返回类型int进行定义,且不带任何参数:int mainvoid{/*…*/}或使用两个参数(此处称为argc和argv),尽管可以使用任何名称,…:int mainnt argc、char*argv[]{/*…*/}或等效名称;或者在其他一些实现定义的方式中,@chqrlie.OMG,我从来没有看到过。谢谢我为我的错误评论道歉。不,int main可以完全这样写,这意味着编译器的参数列表不确定,而int mainvoid则意味着参数列表完全确定且为空,这是完全错误的。那是什么5.1.2.2.1。。。你引用的东西没有参考?您是否生活在main声明为:int mainargc,argv char**argv;{…??这是非常有效的C代码。@LuisColorado:我只是引用C11标准。类似的语言可以在标准的早期版本中找到。int main{…}我确实经历了80年代的C语言编程,我对C标准委员会在清理语言中的一些黑暗角落方面的缓慢感到遗憾。要获得更多的C语言经验需要时间和艰苦的工作……这当然是一次令人谦卑的经历。It MaVaIONE是一个错误…请纠正你的答案。当前的方法是省略main函数的main in main,或者把它们放在int main ARGC中,const char **ARVv},但是不要把错误的参数放进int MaViObj.Myst:恐怕你错了:你的注释对C++是正确的,但对于C来说不是,因为问题被标记了。5.1.2.2.1程序启动程序启动时调用的函数名为main。实现没有声明此函数的原型。应使用返回类型int进行定义,且不带任何参数:int mainvoid{/*…*/}或使用两个参数(此处称为argc和argv),尽管可以使用任何名称,…:int mainnt argc、char*argv[]{/*…*/}或等效名称;或者在其他一些实现定义的方式中,@chqrlie.OMG,我从来没有看到过。谢谢我为我的错误评论道歉。不,int main可以完全这样写,这意味着编译器的参数列表不确定,而int mainvoid则意味着参数列表完全确定且为空,这是完全错误的。那是什么5.1.2.2.1。。。你引用的东西没有参考?您是否生活在main声明为:int mainargc,argv char**argv;{…??这是非常有效的C代码。@LuisColorado:我只是引用C11标准。类似的语言可以在标准的早期版本中找到。int main{…}我确实经历了80年代的C语言编程,我对C标准委员会在清理语言中的一些黑暗角落方面的缓慢感到遗憾。要获得更多的C语言经验需要时间和艰苦的工作……这当然是一次令人谦卑的经历。请向人们说明为什么这些示例不编译,因为知道为什么不需要示例的人,需要示例的人也需要知道原因。请向人们说明为什么这些示例不编译,因为知道为什么不需要示例的人,需要示例的人需要还要知道原因。