while循环需要显式条件,for循环不,为什么?

问题描述:

在C++中,您可以在for循环中有空的条件,例如for (;;)for (int x = 0;; ++x)。但你不能做while()while循环需要显式条件,for循环不,为什么?

当在for循环中省略条件时,条件被假定为true(所以循环永远循环)。为什么while循环没有这种情况,也就是说,不要让while()成为while (true)的别名?

+8

答案可能是2倍:1)与C99向后兼容; 2)因为标准委员会这样说。可能有一些语法原因,为什么'while()'可能不起作用,但从理论上讲,如果他们真的希望它可以被修复。 –

+2

@ZacHowland 1)那么问题是为什么这是在C99的情况;) – leemes

+2

@leemes - 因为C90标准委员会这么说;) –

大概是for-statement中的每个给定子句都是可选的,这是一个副作用。有些for循环不需要赋值的原因是有原因的;有一些其他人不需要条件的原因;还有其他人不需要增量的原因。要求那里有一些最小数量将是不必要的增加的复杂性。

+1

+1被放在一个非常容易理解的方式。 – Annabelle

+0

这回答了为什么'for(;;)'是有效的,但没有解释为什么'while()'不能(这可能是基于意见的)。 –

+1

关键是他们没有着手在控制语句中使条件成为可选的。在for循环的特例中,纯粹是一致的。 – Sneftel

以下是从书深度C秘密

早期的C具有没有单独的运营商&和& &或|和||。 (那是什么?)相反,它使用了“真值上下文”的概念(继承自B和BCPL):在“if”和“while”等之后,期望布尔值,&和|运营商被解释为& &和||现在;在普通表达式中,使用了按位解释。它工作得很好,但很难解释。 (在真值背景下有“*操作员”的概念。)

所以你有它,while()将设置真值的上下文,不能为空或暗示为同样的原因,如果()不能为空,早期语言的机制期望它们不是。

+3

我不明白。如果表达式是* optional *,那么操作符的含义和“上下文”与问题有什么关系? – leemes

+0

为了实现C中的'真值上下文'(如B和BCPL),if()和while()...之后应该有一个布尔值,所以它们不能为空。尽管最初的原因(和&或&&等的含义的解释不再存在),设计被传递给C的更新版本,然后传递给C++。 –

+3

仍然不明白为什么这是一个论据。他们可以这样说**如果**有括号内的内容,那么它是一个布尔表达式上下文。另外,为什么'for'循环的计数不一样? – leemes

我认为主要区别在于表达式陈述

当然,在C两者都没有严格区分,但我要说的for循环:

for (statement; expression; statement) { 
    ... 
} 

的表达是一个布尔表达式,而语句是...这有副作用的语句效果。当然,C不是半功能的;你可以把副作用放在中间表达式中,但它不是惯用的。

然而,有时你不想要的表情,但在一开始,并在每个循环迭代语句是有用的,所以中间表达式是可选的:

// Infinite counter 
int i; 
for (i = 0;;i++) { 
    ... 
} 

这顾名思义是指表达被认为是总是如此

在另一方面,whileif可以只有采取表情。没有什么非常有用的左侧(不像左边的两个有用的语句),如果你省略表达:没有人会写

// Idiot coding 
if (true) { 
    ... 
} 

因为if声明的一点是要检查一些未知是否是真的还是假的!

while相同。 while的要点是要反复做某事,只要条件以表达式的形式为真。这有点像“迭代if”。这就是为什么

while() { 
    ... 
} 

是不合逻辑的,因此不允许。

在而用于逻辑语句之间的差值(),以及(;;)环路之处在于:

  • 在该语句的情况下定义了退出循环

  • 条件在while()的情况下,语句定义为执行循环的条件

假设你看到要进入一个循环,至少需要执行一个条件,而不是退出的条件。

+2

'for'循环的语法包含执行循环的条件,就像'while'循环的语法 – anatolyg

作为每Document

6.8.5.3 for语句

声明for (clause-1 ; expression-2 ; expression-3) 语句行为如下:

  1. 表达表达-2是控制在循环主体的每次执行之前评估的表达式为 。在循环体的每次执行 之后,表达式-3的表达式被评估为空表达式。如果子句-1是一个声明,则声明的任何 标识符的范围是声明的剩余部分和整个循环,包括其他两个表达式;它在 表达式的第一次评估之前达到的执行顺序为 。如果子句-1是表达式,则在控制 表达式的第一次评估之前将其评估为空缺 表达式。158)
  2. 子句-1和表达式-3都可以省略。 省略了 表达式-2被一个非零常数替换。

所以,在for环的情况下,条件将由非零常数和没有这样的实施while环代替。

+0

@downvoters请提一些注释... –

+0

OP想知道标准背后的原因背后的原因;我假定他已经知道C/C++语法 – anatolyg

+0

“省略的表达式-2被非零常量替换。” ?? !!! –

在C++中,你都不允许有一个空的条件里面的for循环... 背后有什么不让while()while(true)别名的说法?

首先,C++(以及C#和许多其他语言)是它们与C向后兼容的方式,所以让我们来谈谈C.

让我们做一些陈述并得出结论。

  1. for循环允许您省略条件的一个很好的理由。
  2. 同样的好理由适用于while循环。
  3. while循环不允许该条件被省略;它是不一致的。
  4. 整个报表的设计选择的一致性是C设计中的一个重要因素。因此,不一致性必定存在不明显的好理由;为什么while循环与for循环不一致有一个很好的理由。

现在问题是“这是什么不明显的好理由?”

但是这个问题只有在上述逻辑链是正确的时才有意义,事实并非如此。在这些陈述中,只有#3实际上是真的! C中的for循环是一个糟糕的设计;它是多余的,让新手感到困惑,其词汇约定与其他语言不一致。它通过简单的while循环为语言提供几乎为零的附加代表力。

有没有人回答你的问题; 正确的回答是完全拒绝这个问题的前提。for循环似乎是合理的,因为它是我们大多数人长大的一个40多岁的错误特征,所以它的怪癖现在是第二性质;这是熟悉的,不是很好的设计。如果我们长大了没有for循环,我们不会添加它。

+1

然而,最近,基于范围的for-loops *被添加,表明对于设计用于表示对序列的迭代的循环的不同胃口。它的语义可能有点多毛,但我认为这更多的是C的抽象序列能力的局限性,而不是一般包含该特征的可取性。 – Sneftel

+1

@Sneftel:哦,不要误会我的意思;我喜欢循环的概念,它抽象了迭代序列的操作。 for循环的根本问题是它的语法*很愚蠢*。分号在逻辑上可以被认为是副作用算子*的序列组成。当你说'A(); B(); C();'在C中,这意味着要顺序组合三个函数调用的副作用。这就是除了foreach循环之外的任何地方,它意味着非常不同的东西。 –

+0

这是一个很好的观点。如果他们为“(a)(b)(c){...}”,甚至“为{a} {c}(b){...}”制定语法,那将会很有趣。毕竟,'a'和'c',在某种意义上应该是块,并且'b'不值得。 – Sneftel