35

我的猜测是它只是让解析更容易,但我不明白为什么。

那么这有什么...

do
{
  some stuff
}
while(test);

more stuff

这比……好

do
{
  some stuff
}
while(test)

more stuff
4

8 回答 8

57

因为你要结束陈述。语句以块(由花括号分隔)或分号结束。“do this while this”是一条语句,不能以块结尾(因为它以“while”结尾),所以它需要一个分号,就像任何其他语句一样。

于 2009-06-02T22:33:46.497 回答
31

如果你看一下 C++ 语法,你会看到迭代语句被定义为

while ( 条件 ) 语句

for ( for-init-statement 条件-opt ; 表达式-opt ) 语句

do 语句 while ( 表达式 ) ;

请注意,只有do-while语句;末尾有一个。所以,问题是为什么 与do-while其他的如此不同以至于它需要额外的;

让我们仔细看看:两者都forstatementwhile结尾。但以包含在 中的控制表达式结束。该封闭的存在已经允许编译器明确地找到控制表达式的结尾:外部封闭指定表达式结束的位置,因此,整个语句结束的位置。换句话说,终止确实是多余的。do-while()())do-while;

但是,在实践中,这意味着,例如,以下代码

do
{
  /* whatever */
} while (i + 2) * j > 0;

虽然从语法的角度来看是有效的,但实际上会被解析为

do
{
  /* whatever */
} while (i + 2)

*j > 0;

这在形式上是合理的,但并不是很直观。我猜出于这样的原因,决定在do-while语句中添加一个更明确的终止符 - 一个分号。当然,根据@Joe White 的回答,还需要考虑简单明了的一致性:C 中的所有普通(非复合)语句都以 a 结尾;

于 2009-10-25T20:38:39.757 回答
24

这是因为 while 语句在 do-while 循环中是有效的。

如果不需要分号,请考虑不同的行为:

int x = 10;
int y = 10;

do 
  while(x > 0)
    x--;
while(x = y--);
于 2009-06-02T22:46:05.320 回答
9

虽然我不知道答案,但一致性似乎是最好的论据。C/C++ 中的每个语句组都以

  1. 一个分号
  2. 一个大括号

为什么要创建一个两者都不做的构造?

于 2009-06-02T22:34:21.253 回答
7

流控语句一致性

考虑到一致性...

if (expr) statement;
do statement; while (expr);
for (expr; expr; expr) statement;
while (expr) statement;

...所有这些流量控制结构都以分号结尾。

但是,反驳我们可以注意到块语句形式,只有do while分号分隔:

if (expr) { ... }
do { ... } while (expr);
for (expr; expr; expr) { }
while (expr) { }

所以,我们有';' 或'}',但绝不是“裸”的')'。

语句分隔符的一致性

我们至少可以说每个语句必须由;or分隔},并且在视觉上有助于我们区分语句。

如果不需要分号,请考虑:

do statement1; while (expr1) statement2; do ; while (expr2) statement3; while (expr3) statement4;

很难从视觉上将其解决为不同的语句:

do statement1; while (expr1)
statement2;
do ; while (expr2)
statement3;
while (expr3) statement4;

相比之下,在条件告诉您向后寻找,并且下一条语句与该 无关;之后,以下情况更容易解决:whiledowhile

do statement1; while (expr1); statement2; do ; while (expr2); statement3; while (expr3) statement4;

考虑到人们缩进他们的代码以使流程易于理解,这有关系吗?是的,因为:

  • 人们有时会犯错误(或者在修改代码时暂时出错),如果它在视觉上很突出,这意味着它会更容易修复,并且
  • 宏替换可以将许多语句放在一行中,我们有时需要在排除故障或进行 QA 时直观地验证预处理器的输出。

对预处理器使用的影响

同样值得注意的是著名的预处理器 do-while 习语:

#define F(X) do { fn(X); } while (false)

这可以替换如下:

if (expr)
    F(x);
else
    x = 10;

...产量...

if (expr)
    do ( fn(x); } while (false);
else
    x = 10;

如果分号不是语句的一部分do while,那么if语句将被解释为:

if (expr)
    do-while-statement
; // empty statement
else
    x = 10;

...并且,因为在 之后有两个语句if,所以它被认为是完整的,这使得else语句不匹配。

于 2011-04-13T03:16:23.160 回答
3

C 以分号结尾(而 Pascal 以分号分隔)。将分号放在那里是不一致的。

坦率地说,我讨厌在 do 循环中重用 while。我认为重复直到会不那么令人困惑。但是它就是这样啊。

于 2009-06-02T22:35:00.443 回答
1

在 C/C++ 中,空格对结构没有贡献(例如在 python 中)。在 C/C++ 中,语句必须以分号结束。这是允许的:

do
{
  some stuff; more stuff; even more stuff;
}
while(test);
于 2009-06-02T22:34:29.460 回答
1

我的回答是,当我们没有在do.....while();循环终止时包含分号时,编译器可能会感到困惑。没有这个就不清楚了:

  1. 什么时候结束?
  2. 如果while 可以在do 循环之后立即执行一个单独的循环。

这就是为什么我们在循环末尾包含分号do......while,以指示如果条件为假,循环将在此处终止。

于 2011-09-24T15:19:35.400 回答