在C / C ++中为什么要做while(表达式);需要半结肠?

时间:2009-06-02 22:31:17

标签: c++ c language-design

我的猜测是它只是简化了解析,但我看不清楚原因。

那么这有什么......

do
{
  some stuff
}
while(test);

more stuff

这比...更好。

do
{
  some stuff
}
while(test)

more stuff

8 个答案:

答案 0 :(得分:57)

因为你要结束陈述。语句以块(由大括号分隔)或分号结束。 “执行此操作时这是一个单独的语句,并且不能以块结尾(因为它以”while“结尾),因此它需要一个分号,就像任何其他语句一样。

答案 1 :(得分:30)

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

  

while( 条件 声明

     

for( for-init-statement condition -opt ; expression -opt )< / strong> 声明

     

执行 声明 while( 表达式 );

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

让我们仔细看看:while和常规do-while都以语句结束。但是()()中包含的控制表达式结尾。封闭)的存在已经允许编译器明确地找到控制表达式的结尾:外部结束do-while指定表达式结束的位置,因此指定整个;语句的位置结束。换句话说,终止do { /* whatever */ } while (i + 2) * j > 0; 确实是多余的。

然而,在实践中,这意味着,例如,以下代码

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

*j > 0;

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

do-while

这是正式的声音,但它并不是非常直观。我猜想由于这些原因,决定在;语句中添加一个更明确的终结符 - 分号。当然,根据@Joe White的回答,还要考虑简单和简单的一致性:C中的所有普通(非复合)语句都以{{1}}结尾。

答案 2 :(得分:24)

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

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

int x = 10;
int y = 10;

do 
  while(x > 0)
    x--;
while(x = y--);

答案 3 :(得分:9)

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

终止
  1. 分号
  2. 大括号
  3. 为什么要创建一个既不会执行的构造呢?

答案 4 :(得分:6)

流程控制语句一致性

考虑到一致性......

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;

是否重要,因为人们缩进他们的代码以使流程可以理解?是的,因为:

  • 人们有时会犯错误(或者在代码被按摩时暂时出现错误),如果它在视觉上突出显示意味着它将更容易修复,
  • 宏替换可以在一行上抛出大量语句,我们偶尔需要在排除故障或进行质量检查时直观地验证预处理器输出。

对预处理器使用的影响

值得注意的是着名的预处理器做成语:

#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语句无法匹配。

答案 5 :(得分:3)

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

坦率地说,我讨厌对do循环重用while。我认为重复 - 直到本来不那么令人困惑。但事实就是如此。

答案 6 :(得分:1)

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

do
{
  some stuff; more stuff; even more stuff;
}
while(test);

答案 7 :(得分:1)

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

  1. 什么时候结束?
  2. 如果while可以在do循环之后立即执行单独的循环。
  3. 这就是我们在do......while循环结束时包含分号的原因,表示如果条件为假,循环将在此处终止。