在c中為什麼經常看到for( ; ; )這樣的語句,而不直接用while(1)?

在單片機,或者acm競賽中常常看到用for(; ; )而不是while(1)寫循環?明顯後者讀起來會友好點,有什麼效率上的優化嗎?


for(;;)循環是C語言作者推薦的標準方法,同時還是C++作者推薦的標準方法。省略了循環條件,表示無條件循環。

在該寫循環條件地方,不寫條件,不寫就是沒有,含義自然就是無條件循環,從語義上講 for(;;)循環顯然更符合語義。

while(1)在某些編譯器會報警告的。在該寫循環條件時寫1,可能會被認為是輸入恆真表達式而給警告。

在不加編譯優化的情況下,while 的用法在某些老舊的編譯器中會導致強行與1比較一次。而 for 循環的這種形式永遠會被編譯器正確識別為無條件循環。

當然,他們在編譯器上的區別一般可以忽略不計。for 循環只是在語義上對程序員更友好,含義為 forever ,而 while 循環則難以用英文讀出其含義。


以下幾個原因:

(1)一些古老的編譯器仍然會給while(1)生成條件跳轉(判斷1是否不等於0),而for(;;)都是直接按無條件跳轉實現。這樣效率上前者就略低一些。

(2)while(1)在一些環境下會報conditional expression is constant的warning(比如VS上warning級別開到4),而for(;;)就不會。


C程序員傳統上喜歡for(; ;)的高效性;因為早期的編譯器經常強製程序在每次執行while循環體時測試條件1。但是對於現代編譯器來說,在性能上兩種無限循環應該沒有差別。

出自《C語言程序設計 現代方法》p83


性能上沒差別。while寫法會讓某些編譯器或代碼分析工具報warning。


少一個字元


看了一下gcc的彙編代碼,現在編譯器已經能做到一樣了。至於古老的傳說

gcc 彙編出來的兩個一模一樣,都變成了一個跳轉。

.file "while.c"
.def ___main; .scl 2; .type 32; .endef
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
call ___main
L2:
jmp L2
.ident "GCC: (tdm-1) 5.1.0"


  1. 在大多數編譯器中,這兩個infinite loop是沒有區別的,其執行效率取決於其中的body-statement;
  2. 在Bjarne Stroustrup所著的《C++程序設計語言》第6.1.1小節中講到:

奇特的記法形式for(;;)是人們描述無限循環的一種標準形式,你可以將它讀作「永遠」。這是for-statement的一種退化形式;我們也可以用while(true)代替它。

想要讀起來更友好嗎?

#define EVER ;;
for (EVER) {
//...
}

更新一下:搬運兩個Stack Overflow問題

  1. while (1) Vs. for (;;) Is there a speed difference?

  2. Is 「for(;;)」 faster than 「while (TRUE)」? If not, why do people use it?


原因之一:while (1)還有while (true), while (TRUE)等寫法,亂。


我在一篇博客上看到過這個問題。是關於程序設計優化方面的,是while循環循環一次比for(;;)多三行彙編代碼。如果是幾次循環還好。可是總while時總會希望是無限次循環的。若是這麼算的話。用for節省的空間就很樂觀了。


我個人喜歡while(1)。 因為for (;;)像哭臉,不吉利。(誤)


編譯器優化後沒啥區別,除了裝X


個人好惡,沒有區別。可以用objdump反彙編(或更簡單的gcc -S)查看目標代碼的差異。


執行效率上基本上是一樣的,我覺得是根據個人的編程習慣


能用for語句解決的問題99%的人都不會使用while語句。


C的優點有許多,但缺點也不少.其中一個就是你所提出的這個問題的背後反映出來的備受詬病的"C的標準飽受爭議,不同的編譯器有不同的編譯標準."


推薦閱讀:

為什麼大多數的C++的開源庫都喜歡自己實現一個string?
C++或QT項目如何進行CI(Continuous Integration)?
Clang 解析錯誤和報錯的機制?
Visual studio中的「添加引用」是什麼意思?
C++中的數組與指針的一個小疑惑?

TAG:編程 | C編程語言 | 彙編語言 | C | ACM競賽 |