【发布时间】:2009-06-02 22:31:17
【问题描述】:
我的猜测是它只是让解析更容易,但我不明白为什么。
那么这有什么...
do
{
some stuff
}
while(test);
more stuff
这比……好
do
{
some stuff
}
while(test)
more stuff
【问题讨论】:
标签: c++ c language-design
我的猜测是它只是让解析更容易,但我不明白为什么。
那么这有什么...
do
{
some stuff
}
while(test);
more stuff
这比……好
do
{
some stuff
}
while(test)
more stuff
【问题讨论】:
标签: c++ c language-design
因为你要结束陈述。语句以块(由花括号分隔)或分号结束。 “do this while this”是一条语句,不能以块结尾(因为它以“while”结尾),所以它需要一个分号,就像任何其他语句一样。
【讨论】:
如果你看一下 C++ 语法,你会发现迭代语句被定义为
while ( 条件 ) 语句
for ( for-init-statement 条件-opt ; 表达式-opt ) 声明
做 语句 while ( 表达式 ) ;
请注意,只有do-while 语句的末尾有;。所以,问题是为什么do-while 与其他的如此不同以至于它需要额外的;。
让我们仔细看看:for 和普通的while 都以 语句 结尾。但是do-while 以包含在() 中的控制表达式 结束。封闭() 的存在已经允许编译器明确地找到控制表达式的结尾:外部封闭) 指定表达式结束的位置,因此,整个do-while 语句结束的位置。也就是说,终止;确实是多余的。
但是,在实践中这意味着,例如,下面的代码
do
{
/* whatever */
} while (i + 2) * j > 0;
while valid 从语法上看,确实会被解析为
do
{
/* whatever */
} while (i + 2)
*j > 0;
这在形式上是合理的,但实际上并不直观。我猜出于这样的原因,决定在do-while 语句中添加一个更明确的终止符——一个分号。当然,根据@Joe White 的回答,还需要考虑简单明了的一致性:C 中的所有普通(非复合)语句都以 ; 结尾。
【讨论】:
while 语句将与外部do 错误关联时,接受答案的评论者之一实际上感到困惑。这根本不是真的。语法经过专门设计,不会让这种情况发生,无论是否使用分号。
这是因为 while 语句在 do-while 循环中是有效的。
如果不需要分号,请考虑不同的行为:
int x = 10;
int y = 10;
do
while(x > 0)
x--;
while(x = y--);
【讨论】:
do while(...); 不合法。一个空的 do-while 循环写成:do ; while(...); 或 do {} while(...); 否则它不会编译。
; 要求,代码会以某种方式被误解。实际上,语言语法(即使是当前形式)不允许对上述代码进行任何所谓的误解,即使删除了结尾的 ; 要求。 Benoît 是对的:该示例没有解释与该问题相关的任何内容。这个答案是不正确的。我允许 Don 暗示我遗漏的东西的可能性,但在他澄清他的意思之前,这是一个可靠的 -1。
do while (x > 0) x--; 不能被误解为一个空循环,其控制表达式为 x > 0,后跟 x--; 语句。这是因为空循环必须写成do ; while (expr)或do {} while (expr)——循环体必须是一个语句。
do while (x) 是不合法的:您必须使用 do ; while (x) 或执行 { } while (x)`。 Benoît 和 AndreyT 是正确的。
虽然我不知道答案,但一致性似乎是最好的论据。 C/C++ 中的每个语句组都由
终止为什么要创建一个两者都不做的构造?
【讨论】:
考虑一致性...
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) { }
所以,我们有';'或 '}',但绝不是“裸露的”')'。
我们至少可以说每个语句都必须由; 或} 分隔,并且在视觉上有助于我们区分语句。
如果不需要分号,请考虑:
do statement1; while (expr1) statement2; do ; while (expr2) statement3; while (expr3) statement4;
很难从视觉上将其解决为不同的语句:
do statement1; while (expr1)
statement2;
do ; while (expr2)
statement3;
while (expr3) statement4;
相比之下,在while 条件告诉您向后寻找do 并且下一条语句与while 无关之后,以下情况更容易解决为;:
do statement1; while (expr1); statement2; do ; while (expr2); statement3; while (expr3) statement4;
考虑到人们缩进他们的代码以使流程易于理解,这是否重要?是的,因为:
同样值得注意的是著名的预处理器 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 语句不匹配。
【讨论】:
C 以分号结尾(而 Pascal 以分号分隔)。将分号放在那里会不一致。
坦率地说,我讨厌在 do 循环中重用 while。我认为重复直到会不那么令人困惑。但事实就是如此。
【讨论】:
在 C/C++ 中,空格对结构没有贡献(例如在 python 中)。在 C/C++ 语句中,必须 以分号结束。这是允许的:
do
{
some stuff; more stuff; even more stuff;
}
while(test);
【讨论】:
我的回答是,当我们没有在do.....while(); 循环的终止中包含分号时,编译器可能会感到困惑。没有这个就不清楚了:
这就是为什么我们在do......while 循环的末尾包含分号,以表明如果条件为假,循环将在此处终止。
【讨论】: