2010-08-21 948 views
5

我看到很多書所用的不同的約定我讀了,在那裏你會創建一個無限循環或者循環結構,如:無限循環和循環之間有什麼區別?

while() 
    foo(); 
for(;;) 
    foo(); 

不過說真的,什麼是我應該知道的區別是什麼?哪一個更好?

回答

7

它們在語義上是等效的。 (x;y;z) { foo; }相當於x; while (y) { foo; z; }。它們與標準的其他版本並不完全等價,在for (int x = 0; y; z)的示例中,x的範圍是for塊,並且在循環結束後超出範圍,而int x; while (y) x在循環結束後仍處於範圍內。

另一個區別是for將缺失的y解釋爲TRUE,而while必須提供表達式。 for (;;) { foo; }是好的,但while() { foo; }不是。

+1

僅供參考,問題是詢問無限循環,而不是針對vs的語義,而一般而言。 – 2010-08-21 01:17:47

+3

如果你想避開聲明'x'的地方,你可以說'for(x; y; z){foo; }'相當於'{x; while(y){foo; Z者除外; }}。 – 2010-08-21 01:29:18

+0

至於語義,for-loops的C語言標準允許構造一個與while循環相同的for循環。 然而,這與for循環的深層語義理解相沖突,它總是包含循環變體(爲了方便的原因,通常將其定義爲相同的正數)。 對於一致的語義,應該在執行循環(for-loops)之前明確迭代次數已知的循環之間的清楚分離,以及在執行之前迭代次數未知的循環(while循環)。 – Schedler 2010-08-21 03:14:41

0

第一個不會編譯。您至少需要:while(true)。它們在語義上是等效的。這是一個風格/個人選擇的問題。

2

這裏是我在調試模式下用VS2010反彙編看到的一個小差異。不確定,如果它足以作爲顯着普遍真差異(跨所有編譯器和所有優化)。

所以概念性這些環是相同的,但在一個處理器級,具有無限的消息循環,用於附加的/不同的指令的時鐘週期可以是不同的,並提出一些差異。

while(1) 
004113DE mov   eax,1      **// This is the difference** 
004113E3 test  eax,eax      **// This is the difference** 
004113E5 je   main+2Eh (4113EEh) 
     f(); 
004113E7 call  f (4110DCh) 
004113EC jmp   main+1Eh (4113DEh)   **// This is the difference** 
    for(;;) 
     f(); 
004113EE call  f (4110DCh) 
004113F3 jmp   main+2Eh (4113EEh)   **// This is the difference** 
} 
+2

啓用任何優化後,此差異絕對不存在。 – 2010-08-21 01:46:19

+0

區別僅在於調試模式默認關閉了優化。前3行實際上是檢查'1!= 0',即條件是否成立。 – casablanca 2010-08-21 01:48:30

+0

而'jmp'的區別只是一個稍微不同的偏移量。 – 2010-08-21 01:57:15

1

沒有區別。

但是

而()FOO();

是不一樣的那

爲(;; FOO();)

切記!如果你把foo()語句之前突破的同時,FOO()不執行,但如果你打破了,FOO()執行...

0

他們都是相同的。現代編譯器發出相同兩個..有趣的(歷史?)的爲(;;)更受歡迎..帕斯卡程序員做了的#define(;;)曾經和永久使用代碼{//代碼}