为什么在C语言中可以使用多个分号?

12

在C语言中,我可以这样做:

int main()
{
 printf("HELLO WORLD");;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
}

而且它运行成功了!为什么会这样呢?

我的个人想法是:分号是一个无操作(从维基百科)指示符,有一堆分号的字符串与只有一个分号告诉C语言一个语句已结束具有相同的意义。


分号用于分隔语句。在这些分号之间没有告诉编译器执行任何操作,所以它为什么不能运行呢? - Blender
3
@Blender:在C语言中,分号并不是真正的语句分隔符,它实际上是语句终止符。有一些语言使用分号作为语句分隔符,在这些语言中,块中最后一个语句后面的分号是可选的。 - Dietrich Epp
1
在任何编程语言中,编写没有任何用处的代码都是有效的。你认为C会有例外吗? - Peter G.
@DietrichEpp:不一定是可选的。例如,在 Pascal 中(至少由 Wirth 定义),在 else 之前立即放置分号是一个错误——编译器不会接受它。 - Jerry Coffin
5个回答

13
分号用于终止语句... 连续的分号表示无操作语句(正如您所说)。请考虑:
while (x[i++] = y[j++])
    ;

这里,所有的工作都在循环测试条件中完成,因此需要一个空语句。但是,即使没有控制循环,也允许使用空语句。

为什么?

嗯,预处理器的许多用途可能会扩展到一些实际的C代码,或者基于一些早期的定义而被删除,但是......

 MY_MACRO1();
 MY_MACRO2();

预处理器只能替换MY_MACROX()文本,不能移除尾随的分号,有可能是一个空语句之后的分号。如果编译器拒绝这个操作,那么使用预处理器将会更加困难,或者调用预处理器将不再像非预处理器函数调用一样(需要在宏定义中输出分号,并且在使用时调用方需要避免尾随分号),这将使得实现对于性能、调试和定制化目的的聪明宏替换函数更加困难。


10

C语言允许使用空语句。它们可以用于像空循环这样的场景:

while (*d++ = *s++)
   ; // null statement.

你刚刚创建了一系列它们。
它还允许不完全为空的语句,例如:
0;
1+1;

这两个都包含表达式,但没有副作用,因此它们实际上并没有做任何事情。虽然允许这样做,但编译器可能会发出警告。

一个好的编译器通常不会为上述任何内容生成任何代码(大多数甚至在关闭优化时也不会生成代码,我无法想象开启优化后会生成代码的编译器)。


8

两个分号在一起会生成一个空语句。C语言允许有空语句 - 它们不会产生任何代码。


4
对于学究们:是的,毫无疑问,“for(;;)”包含了两个分号,但不是一个空语句。 - Jerry Coffin
或者最终它们会生成“nop”指令。 - Op De Cirkel
@JerryCoffin 即使在 for 循环中它们是空语句,它们也是评估为 true 的空语句... - aleroot
1
@aleroot:for语句的语法是:for (clause-1; expression-2; expression-3) statement。正如您所看到的,被控制的是一个语句,但其他的只是表达式,而不是语句(好吧,clause-1可以是表达式或声明,但它仍然不是语句)。 - Jerry Coffin
@JerryCoffin:从技术上讲,声明也是一种语句,对吧? - Jo So
1
@JoSo:按照当前标准,是的。但他们已经稍微改变了语法规范,所以现在是 for ( init-statement condition ; expression ),而 init-statement 明确是一个语句。我得挖出一份旧草案才能确定,但我 认为 那时候,for 循环中的第一个子句是一个独特的东西,无法追溯到实际的语句(或者我的记忆只是太差了——在我这个年龄,这种情况太常见了)。 - Jerry Coffin

3

因为在C语言中分号代表一个语句的结束,在你的情况下,更多的分号代表更多的空语句......这没有问题,它们只是空语句。


0
分号是行终止符,意味着它们告诉代码已到达行末,然后执行下一行代码。
一个证明是你可以在单行中编写你的代码,不包括指令。
main() { cout << "ENTER TWO NUMBERS"; cin >> a; cin >> b; cout << "The sum of two numbers are" << a+b; << return 0;}

这可能意味着

main() { cout << "输入两个数字"[THEN] cin >> a[THEN] cin >> b[THEN] cout << "两个数字的和为" << a+b[THEN] << return 0[THEN]}

所以如果你放置多个分号,就像 THEN, THEN, THEN, THEN,你的个人想法是正确的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接