在 C/C++ 为什么 do while(表达式); 需要分号吗?

发布于 2024-07-22 03:30:40 字数 208 浏览 10 评论 0原文

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

那么这有什么...

do
{
  some stuff
}
while(test);

more stuff

这比...更好

do
{
  some stuff
}
while(test)

more stuff

My guess is it just made parsing easier, but I can't see exactly why.

So what does this have ...

do
{
  some stuff
}
while(test);

more stuff

that's better than ...

do
{
  some stuff
}
while(test)

more stuff

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

负佳期 2024-07-29 03:30:40

因为你正在结束声明。 语句以块(由大括号分隔)或分号结束。 “do this while this”是单个语句,不能以块结尾(因为它以“while”结尾),因此它需要一个分号,就像任何其他语句一样。

Because you're ending the statement. A statement ends either with a block (delimited by curly braces), or with a semicolon. "do this while this" is a single statement, and can't end with a block (because it ends with the "while"), so it needs a semicolon just like any other statement.

仄言 2024-07-29 03:30:40

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

while ( 条件 ) 语句

for ( for-init-statement 条件-opt ; 表达式-opt )< /strong> 声明

do 语句 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 中的所有普通(非复合)语句都以 ; 结尾。

If you take a look at C++ grammar, you'll see that the iteration statements are defined as

while ( condition ) statement

for ( for-init-statement condition-opt ; expression-opt ) statement

do statement while ( expression ) ;

Note that only do-while statement has an ; at the end. So, the question is why the do-while is so different from the rest that it needs that extra ;.

Let's take a closer look: both for and regular while end with a statement. But do-while ends with a controlling expression enclosed in (). The presence of that enclosing () already allows the compiler to unambiguously find the end of the controlling expression: the outer closing ) designates where the expression ends and, therefore, where the entire do-while statement ends. In other words, the terminating ; is indeed redundant.

However, in practice that would mean that, for example, the following code

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

while valid from the grammar point of view, would really be parsed as

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

*j > 0;

This is formally sound, but it is not really intuitive. I'd guess that for such reasons it was decided to add a more explicit terminator to the do-while statement - a semicolon. Of course, per @Joe White's answer there are also considerations of plain and simple consistency: all ordinary (non-compound) statements in C end with a ;.

妥活 2024-07-29 03:30:40

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

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

int x = 10;
int y = 10;

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

It's because while statements are valid within a do-while loop.

Consider the different behaviors if the semicolon weren't required:

int x = 10;
int y = 10;

do 
  while(x > 0)
    x--;
while(x = y--);
一场春暖 2024-07-29 03:30:40

虽然我不知道答案,但一致性似乎是最好的论据。 为什么

  1. C/C++ 中的每个语句组都以分号和大括号
  2. 终止

要创建一个两者都没有的构造?

While I don't know the answer, consistency seems like the best argument. Every statement group in C/C++ is either terminated by

  1. A semicolon
  2. A brace

Why create a construct which does neither?

删除会话 2024-07-29 03:30:40

流程控制语句一致性

考虑一致性...

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;

...yields...

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 语句不匹配。

Flow control statement consistency

Considering consistency...

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

...all these flow-control constructs, end with a semicolon.

But, countering that we can note that of the block-statement forms, only do while is semicolon delimited:

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

So, we have ';' or '}', but never a "bare" ')'.

Consistency of statement delimiters

We can at least say that every statement must be delimited by ; or }, and visually that helps us distinguish statements.

If no semicolon were required, consider:

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

It's very difficult to visually resolve that to the distinct statements:

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

By way of contrast, the following is more easily resolved as a ; immediately after a while condition tells you to seek backwards for the do, and that the next statement is unconnected to that while:

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

Does it matter, given people indent their code to make the flow understandable? Yes, because:

  • people sometimes make mistakes (or have them transiently as the code's massaged) and if it visually stands out that means it will be fixed more easily, and
  • macro substitutions can throw together lots of statements on one line, and we occasionally need to visually verify the preprocessor output while troubleshooting or doing QA.

Implications to preprocessor use

It's also worth noting the famous preprocessor do-while idiom:

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

This can be substituted as follows:

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

...yields...

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

If the semicolon wasn't part of the do while statement, then the if statement would be interpreted as:

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

...and, because there are two statements after the if, it's considered complete, which leaves the else statement unmatched.

白云不回头 2024-07-29 03:30:40

C 以分号结尾(而 Pascal 以分号分隔)。 在那里删除分号会不一致。

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

C is semicolon-terminated (whereas Pascal is semicolon-separated). It would be inconsistent to drop the semicolon there.

I, frankly, hate the reuse of the while for the do loop. I think repeat-until would have been less confusing. But it is what it is.

掩饰不了的爱 2024-07-29 03:30:40

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

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

In C/C++ whitespace don't contribute to structure (like e.g. in python). In C/C++ statements must be terminated with a semicolon. This is allowed:

do
{
  some stuff; more stuff; even more stuff;
}
while(test);
番薯 2024-07-29 03:30:40

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

  1. do什么时候结束?
  2. 如果 while 可以在 do 循环之后紧跟着一个单独的循环。

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

My answer is that, the compiler may get confusion, when we didn't include the semicolon in the termination of do.....while(); loop. Without this it is not clear about:

  1. when the do ends?
  2. If the while may a separate loop followed immediately after do loop.

That's why we include semicolon in the end of do......while loop, to indicate the loop is terminating here if the condition is false.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文