2014-02-11 316 views
22

在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標準委員會這麼說;) –

回答

30

大概是for-statement中的每個給定子句都是可選的,這是一個副作用。有些for循環不需要賦值的原因是有原因的;有一些其他人不需要條件的原因;還有其他人不需要增量的原因。要求那裏有一些最小數量將是不必要的增加的複雜性。

+1

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

+0

這回答了爲什麼'for(;;)'是有效的,但沒有解釋爲什麼'while()'不能(這可能是基於意見的)。 –

+1

關鍵是他們沒有着手在控制語句中使條件成爲可選的。在for循環的特例中,純粹是一致的。 – Sneftel

8

以下是從書深度C祕密

早期的C具有沒有單獨的運營商&和& &或|和||。 (那是什麼?)相反,它使用了「真值上下文」的概念(繼承自B和BCPL):在「if」和「while」等之後,期望布爾值,&和|運營商被解釋爲& &和||現在;在普通表達式中,使用了按位解釋。它工作得很好,但很難解釋。 (在真值背景下有「頂級操作員」的概念。)

所以你有它,while()將設置真值的上下文,不能爲空或暗示爲同樣的原因,如果()不能爲空,早期語言的機制期望它們不是。

+3

我不明白。如果表達式是* optional *,那麼操作符的含義和「上下文」與問題有什麼關係? – leemes

+0

爲了實現C中的'真值上下文'(如B和BCPL),if()和while()...之後應該有一個布爾值,所以它們不能爲空。儘管最初的原因(和&或&&等的含義的解釋不再存在),設計被傳遞給C的更新版本,然後傳遞給C++。 –

+3

仍然不明白爲什麼這是一個論據。他們可以這樣說**如果**有括號內的內容,那麼它是一個布爾表達式上下文。另外,爲什麼'for'循環的計數不一樣? – leemes

3

我認爲主要區別在於表達式陳述

當然,在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() { 
    ... 
} 

是不合邏輯的,因此不允許。

-3

在而用於邏輯語句之間的差值(),以及(;;)環路之處在於:

  • 在該語句的情況下定義了退出循環

  • 條件在while()的情況下,語句定義爲執行循環的條件

假設你看到要進入一個循環,至少需要執行一個條件,而不是退出的條件。

+2

'for'循環的語法包含執行循環的條件,就像'while'循環的語法 – anatolyg

1

作爲每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被非零常量替換。」 ?? !!! –

8

在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