while循环需要显式条件,for循环不,为什么?
在C++中,您可以在for循环中有空的条件,例如for (;;)
或for (int x = 0;; ++x)
。但你不能做while()
。while循环需要显式条件,for循环不,为什么?
当在for循环中省略条件时,条件被假定为true
(所以循环永远循环)。为什么while
循环没有这种情况,也就是说,不要让while()
成为while (true)
的别名?
以下是从书深度C秘密:
早期的C具有没有单独的运营商&和& &或|和||。 (那是什么?)相反,它使用了“真值上下文”的概念(继承自B和BCPL):在“if”和“while”等之后,期望布尔值,&和|运营商被解释为& &和||现在;在普通表达式中,使用了按位解释。它工作得很好,但很难解释。 (在真值背景下有“顶级操作员”的概念。)
所以你有它,while()
将设置真值的上下文,不能为空或暗示为同样的原因,如果()不能为空,早期语言的机制期望它们不是。
我认为主要区别在于表达式和陈述。
当然,在C两者都没有严格区分,但我要说的for循环:
for (statement; expression; statement) {
...
}
的表达是一个布尔表达式,而语句是...这有副作用的语句效果。当然,C不是半功能的;你可以把副作用放在中间表达式中,但它不是惯用的。
然而,有时你不想要的表情,但在一开始,并在每个循环迭代语句是有用的,所以中间表达式是可选的:
// Infinite counter
int i;
for (i = 0;;i++) {
...
}
这顾名思义是指表达被认为是总是如此
在另一方面,while
和if
可以只有采取表情。没有什么非常有用的左侧(不像左边的两个有用的语句),如果你省略表达:没有人会写
// Idiot coding
if (true) {
...
}
因为if
声明的一点是要检查一些未知是否是真的还是假的!
与while
相同。 while
的要点是要反复做某事,只要条件以表达式的形式为真。这有点像“迭代if
”。这就是为什么
while() {
...
}
是不合逻辑的,因此不允许。
在而用于逻辑语句之间的差值(),以及(;;)环路之处在于:
在该语句的情况下定义了退出循环
的条件在while()的情况下,语句定义为执行循环的条件
假设你看到要进入一个循环,至少需要执行一个条件,而不是退出的条件。
'for'循环的语法包含执行循环的条件,就像'while'循环的语法 – anatolyg
作为每Document:
6.8.5.3 for语句
声明
for (clause-1 ; expression-2 ; expression-3)
语句行为如下:
- 表达表达-2是控制在循环主体的每次执行之前评估的表达式为 。在循环体的每次执行 之后,表达式-3的表达式被评估为空表达式。如果子句-1是一个声明,则声明的任何 标识符的范围是声明的剩余部分和整个循环,包括其他两个表达式;它在 表达式的第一次评估之前达到的执行顺序为 。如果子句-1是表达式,则在控制 表达式的第一次评估之前将其评估为空缺 表达式。158)
- 子句-1和表达式-3都可以省略。 省略了 表达式-2被一个非零常数替换。
所以,在for
环的情况下,条件将由非零常数和没有这样的实施while
环代替。
@downvoters请提一些注释... –
OP想知道标准背后的原因背后的原因;我假定他已经知道C/C++语法 – anatolyg
“省略的表达式-2被非零常量替换。” ?? !!! –
在C++中,你都不允许有一个空的条件里面的for循环... 背后有什么不让
while()
是while(true)
别名的说法?
首先,C++(以及C#和许多其他语言)是它们与C向后兼容的方式,所以让我们来谈谈C.
让我们做一些陈述并得出结论。
-
for
循环允许您省略条件的一个很好的理由。 - 同样的好理由适用于
while
循环。 -
while
循环不允许该条件被省略;它是不一致的。 - 整个报表的设计选择的一致性是C设计中的一个重要因素。因此,不一致性必定存在不明显的好理由;为什么
while
循环与for
循环不一致有一个很好的理由。
现在问题是“这是什么不明显的好理由?”
但是这个问题只有在上述逻辑链是正确的时才有意义,事实并非如此。在这些陈述中,只有#3实际上是真的! C中的for
循环是一个糟糕的设计;它是多余的,让新手感到困惑,其词汇约定与其他语言不一致。它通过简单的while
循环为语言提供几乎为零的附加代表力。
有没有人回答你的问题; 正确的回答是完全拒绝这个问题的前提。for
循环似乎是合理的,因为它是我们大多数人长大的一个40多岁的错误特征,所以它的怪癖现在是第二性质;这是熟悉的,不是很好的设计。如果我们长大了没有for
循环,我们不会添加它。
然而,最近,基于范围的for-loops *被添加,表明对于设计用于表示对序列的迭代的循环的不同胃口。它的语义可能有点多毛,但我认为这更多的是C的抽象序列能力的局限性,而不是一般包含该特征的可取性。 – Sneftel
@Sneftel:哦,不要误会我的意思;我喜欢循环的概念,它抽象了迭代序列的操作。 for循环的根本问题是它的语法*很愚蠢*。分号在逻辑上可以被认为是副作用算子*的序列组成。当你说'A(); B(); C();'在C中,这意味着要顺序组合三个函数调用的副作用。这就是除了foreach循环之外的任何地方,它意味着非常不同的东西。 –
这是一个很好的观点。如果他们为“(a)(b)(c){...}”,甚至“为{a} {c}(b){...}”制定语法,那将会很有趣。毕竟,'a'和'c',在某种意义上应该是块,并且'b'不值得。 – Sneftel
答案可能是2倍:1)与C99向后兼容; 2)因为标准委员会这样说。可能有一些语法原因,为什么'while()'可能不起作用,但从理论上讲,如果他们真的希望它可以被修复。 –
@ZacHowland 1)那么问题是为什么这是在C99的情况;) – leemes
@leemes - 因为C90标准委员会这么说;) –