[ C++ ] While 迴圈與 do-While 迴圈用法及使用時機

 

C++ 中,有提供 While 迴圈(While loop), 與 do-While 迴圈兩種,While loop 為前測式迴圈,而 do-While loop 為後測式迴圈,雖然是基本迴圈,但也是初學者最容易誤解,最容易寫錯的迴圈,本文將詳細講解 While loop 與 do-While loop 的定義,用法,分別,使用時機,及常犯錯誤。

 

先備知識等級: 須先了解 for 迴圈及其應用

約需花 20 分鐘閱讀

{{目錄}}

while 迴圈的邏輯                      do-while 迴圈的邏輯

while 迴圈語法定義                   do-while 迴圈語法定義

使用 while 迴圈時的                  使用 do-while 迴圈時的

常見錯誤                                     常見錯誤

while 迴圈使用時機                   do-while 迴圈使用時機

whiledo-while 應用上的差異

 

 

While loop 的邏輯: Untitled Diagram (1).png

由於會在進入迴圈前判斷條件,因此稱為前測式迴圈

 

While loop 的語法: 

while ( condition ) statement

while (   條件   )  陳述句 

while_example1.png

注意,雖然在 C++ 的定義中 while loop 是不帶 { } 的,但學校通常都是教 while ( condition ) { statement } ,這是因為通常 statement 的部分會超過 1 句陳述句,若沒有 { },則 while 會以 condition 後的第一句陳述句為迴圈本體(loop body)。所以如果我們將上方 while 迴圈中的 { } 拿掉:

while_example1_wrong.png

雖然這段程式碼可以編譯成功,但卻隱藏了一個邏輯錯誤。因為當此 while loop 執行時,只會將  j ++; 視為 loop body ,因此   i ++; 將不會被讀到 (讀到 j ++ 後程式就回到開頭去判斷條件),而因為 i ++; 沒有被讀到,所以 i 的值將永遠等於 0;意味著條件永遠成立(因為 0 恆小於 3),程式便卡在這個迴圈中無法跳出,此 loop 就成為了一個無窮迴圈 (infinite loop) ,而這種錯誤往往難以被察覺。

while_example1_wrong_output.png

上圖可以看出,雖然 GCC 編譯成功,但真正執行時,程式卻會卡住而無法繼續(並且由於產生了無窮迴圈,導致 j 的值正在不斷的增加)。因此,使用 while loop 時,請養成使用 { } 的好習慣(事實上寫任何迴圈都應該要養成這個習慣),並確保 loop body 不會造成無窮迴圈,除非那是你的目的。

 

While loop 的使用時機:

常用但不限於

1.需要重複判斷,且無法估算需要判斷的次數
  例如:臺灣手機號碼格式必須為 09 開頭,且總共為 10 個數字。假如你今天寫了一個讀取手機號碼的程式,由於你無法保證不會有小屁孩故意輸入 12345678,或是 ABCDEFGH,且一直持續這樣玩,所以這時就適合用 while 迴圈,則不管他輸入幾次,只有格式正確時程式才會進到下一步。

 

2.在某個事件發生盡可能地執行某個動作

  例如:在達到當月的網路流量限制前,儘可能的下載檔案。 就算你並不知道當月流量限制是多少,但  While 迴圈則可以保證只有在流量恰好到達上限時,檔案才會停止下載。

 

下面介紹 do-while loop

 

do-while loop 的邏輯: do-while.png

由於條件是在迴圈內容運行完之後才判斷,因此又稱為後測式迴圈,其特色就是在判斷條件,會先執行迴圈內容

 

do-while loop 的語法:

do statement while ( condition ) ;

do   陳述    while (   條件    ) ;

do-while_example1.png

 while 一樣,在撰寫 statement 時,需要養成 { } 的好習慣。值得一提的是, do-while loop 的後面必須要加上 ; ,因為 do-while loop 的結尾不是  ,需要加上一個 ; 來表示語句結束,這也是新手常忘記的細節。

而另一個需要注意的重點是: 即便條件式在一開始就不成立,do-while loop 仍然會執行至少一次,因為他是在執行完迴圈本體後,才判斷條件;因此就算呼叫迴圈時條件是不成立的,程式在執行一次迴圈本體後才會知道。

 

do-while loop 的使用時機:

雖然幾乎所有 do-while loop 都可以用 while loop 來重現,但有些情況下,使用 do-while loop 能夠更直覺地呈現出程式的流程,甚至使程式更有效率。

常用但不限於

1. 需要先進行某種動作後,再確認條件是否成立

如我想寫一個檢查電子錢包餘額的程式,來確認買家的商品款是否匯入,且直到款項匯入前,這個程式將會一直提醒我款項尚未匯入,使用 do-while loop 的程式思路如下

check_money.png

注: 由於迴圈只有在條件成立時才會繼續執行,而我們希望在餘額未增加時可以持續地跑這個迴圈,

因此條件須設置為 "餘額增加 "

    餘額未增加(成立)   --> 餘額未增加

    餘額未增加(不成立) --> 餘額已增加

假設今天是使用 while loop,則程式流程會變成下圖

check_money_while_loop.png

不難發現,由於 while loop 前測式的性質,我們需要先存取一次電子錢包,才能進行第一次條件的判斷,又因為 while looploop body 是在條件判斷之後,導致我們在迴圈中利用前面的程式碼,必須要在 loop body 再執行一次存取,才能使下一次迴圈有可以判斷的條件;也就是說,使用 while loop 的話,比起 do-while loop 會需要額外存取資料庫一次。

假設今天存取一次需要一段時間(如 20 秒),並且程式中需要多次進行判斷的話,此時使用 while loop 執行起來將會比 do-while loop 花上更多的時間。身為程式設計者,當然必須選擇相對效率較高的寫法

 

下面就用 C++ 來模擬電子錢包的例子: 假設迴圈執行到第三次時,款項將會匯入
我們同時利用 while loopdo-while loop 來模擬檢查餘額的程式

do-while loop:

 

wallet_do-while_output.png

while loop:

wallet_while_output.png

可以看出,使用 while loop 時確實會需要多存取一次錢包,

因為 while loop 在執行完迴圈後,還會再回頭進行條件判斷,因此會比 do-while多判斷一次,但兩種迴圈本體的執行次數都是 3

*若需要錢包模擬程式的原始碼請寄電子郵件至 Ching91203@gmail.com (點擊此連結可直接進入郵件),並說明需要有關 while_do-while loop 的範例程式碼

參考:

https://stackoverflow.com/questions/14973241/why-do-whilecondition-needs-semicolon-at-the-end-of-it-but-whileconditio

https://www.cprogramming.com/tutorial/lesson3.html

https://www.w3schools.com/cpp/cpp_while_loop.asp

https://www.w3schools.com/cpp/cpp_do_while_loop.asp

https://www.geeksforgeeks.org/c-c-while-loop-with-examples/

https://en.cppreference.com/w/cpp/language/do

https://en.cppreference.com/w/cpp/language/statements

https://en.cppreference.com/w/cpp/language/expressions

https://stackoverflow.com/questions/3003456/why-use-a-do-while-loop

https://stackoverflow.com/questions/994905/is-there-ever-a-need-for-a-do-while-loop

https://www.tutorialspoint.com/cplusplus/cpp_loop_types.htm

https://www.cs.utah.edu/~germain/PPS/Topics/while_loops.html

 

arrow
arrow
    創作者介紹
    創作者 資料點 的頭像
    資料點

    資料點

    資料點 發表在 痞客邦 留言(0) 人氣()