為什麼國外的工程師在給單片機做死循環時喜歡用 for(;;) 而不是 while(1)?

在看郭天祥的msp430教程時發現了一個有趣的問題,TI公司及其它公司的工程師給的demo在做死循環時用的是for(;;);而不是常用的while(1);這僅僅是個人習慣的問題還是有更深層次的含義?


for循環明顯在語義上更適合。更容易理解括弧裡面是循環的條件。括弧循環條件根本不寫,就是〖無條件循環〗。即便沒有認識這個結構的也很容易猜到,沒有循環條件就是無條件循環。

但是while(1) 從代碼風格的角度來說並不好,因為它額外的引入了一個常量,這在沒有充分優化的編譯器上一定比無條件for循環效率低,而單片機的編譯器並非總是非常靠譜的。

我個人認為任何條件下,死循環都不應當用while(1),而應當用for循環,事實上很多人正是這麼做的。當然,你可以有不同看法。


難道不是為了少敲兩次鍵盤?


使用mingw編譯測試。

for版本

#include&
int main()
{
for(;;)
{
printf("for
");
}
}

生成彙編:

while版本

#include&
int main()
{
while(1)
{
printf("while
");
}
}

生成彙編:

綜上:沒有什麼區別。


這個問題挺好玩的,從我自己的角度回答一下。

從我的角度來看,我覺得是個人習慣和語言本身倡導的理念結合產生的結果。

首先,for循環從功能上可以完全覆蓋while循環,而程序員一般都會希望用最簡單直接的代碼描述這個複雜的世界,所以一般都會認可「把for循環用熟,就可以不用了解while循環和do...while循環」這種理念。

其次,直接對比for(;;)和while(1),從語義上來說,理解的容易度並沒有很大的區別,如果是追求閱讀的效果,那毫無疑問是while(true)來的最好些,但是考慮到嵌入式C編譯器可能並未支持boolean類型,那隻能:

#ifndef TRUE
#define TRUE (1)
#endif

#ifndef FALSE
#define FALSE (0)
#endif

while (TRUE) {
/* some code */
}

那麼作為「一次性、演示」用的DEMO程序,寫成這樣實在有點。。。讓程序員難以接受。

最後,大家有沒有發現,一般情況下,輸入for(;;)的效率是會高於while(1)的哦(前者字元數比後者少1,而且前者中有兩個連續的「;」字元,輸入起來比後者明顯舒暢 :-)


個人認為這是KR的影響。因為KR的C Programming Language有這樣的範例。

2nd edition里出現過兩次:

1, p55, KR wrote:

"If the test, expr2, is not present, it is taken aspermanently true, so

for (;;) {
...
}

is an ``infinite loop, presumably to be broken by other means, such as a break or return."

Whether to use while or for is largely a matter of personal preference. For example, in

while ((c = getchar()) == || c ==
|| c = )
; /* skip white space characters */

there is no initialization or re-initialization, so the while is most natural.

2, p 75, KR wrote:

"Any name may be defined with any replacement text. For example

#define forever for (;;) /* infinite loop */

defines a new word, forever, for an infinite loop."

既然KR指出使用for和while很大程度上是個人喜好問題,而KR中並沒有使用while(1)來做infinite loop,所以顯而易見這樣的寫法就是主流了。


Maybe like this:

Computer Programming: Is there a difference between using for(;;) and while(1)?


木有人是因為while(1)中的1是魔數嗎?

有嚴(S)格(X)編程規範把所有的數字都認為是邪惡的魔數,不允許出現的...


for(;;)沒有告警,而while(1)有告警。


&<&<想成為嵌入式程序員應該知道的0x10個問題 &>&> 之中有討論過這個問題. 功能都一樣,while(1)更容易理解,for(;;)晦澀。至於輸入多少,一個程序中沒幾個可以忽略。如果不為了標新立異,while(1)沒錯


之前看過一篇文章寫的JDK源碼中,很多地方用了for(;;)而不是while(true),原因是兩者翻譯成彙編語言後,前者只有一條指令,我記得是JMP FOO+23H,而後者有多條指令(包括MOV指令和TEST指令等,具體我忘了),並且用到了臨時的寄存器,所以效率可能稍微低一些吧。

但又會發現這兩者的Java位元組碼是一樣的,我猜想應該是編譯器有優化吧,比如你寫的是while(true),編譯優化成了for(;;)。

不知道單片機開發里是不是類似的原理。


不執著。這純粹是編譯器的事情,編譯器如果是智能的,輸出的結果是一樣的。for的寫法其實很醜。


要我說,for(;;)容易被讀成 forever, 永遠,

while(1)不太好讀,讀出來也不太好按自然語言理解。


通過查看for(;;)和while(1)的彙編代碼可以看出來,前一個更快更省資源!


推薦閱讀:

2016年全球十大MCU供應商排名,NXP超過瑞薩居首|半導體行業觀察
美國大學數學助理教授給您講解為什麼通貨膨脹不貶值DCEU的30億票房,為什麼依然是DCEU勝出。
《銀河護衛隊1》終極彩蛋「疑似」曝光!!

TAG:編程 | 單片機入門 | MCU |