Re: [問題]請教一下for與while為甚麼答案不一樣?

作者: poyenc (髮箍)   2020-09-16 22:35:35
安安, 其實這題不需要真的執行啦! 只要善用簡單的靜態分析 (static
analysis) 技巧就可以知道問題在哪邊. 首先是 for 迴圈的基本定義, 我們可
以用判斷程式碼品質時常用的方法: 資料視覺化 (data visualization) 來為
程式碼片段做著色. for 迴圈裡的程式碼依照責任可以分成四個區塊:
for ( (1) ; (2) ; (3) ) {
(4)
}
雖然通常每個區塊做的事情都不同, 但求值順序卻是固定的, 如果我們想知道
迴圈的商業邏輯, 我們會直接看 (4) , 想知道問題的範圍/大小就看 (2) , 依
此類推. while 迴圈也有這四個區塊存在, 只是寫得比較分散一點:
(1)
while ( (2) ) {
(4)
(3)
}
從上面可以看到, while 迴圈的 (4) 和 (3) 同樣都寫在迴圈的本體內, 在閱
讀上和 for 相比多了區分兩區塊的步驟, 而且 (1) 容易和前面的程式碼混在
一起, 可讀性較差. 因為兩種迴圈是可以互轉的, 在發現有這個問題時, 就可
以嘗試將迴圈改寫, 改寫前先將程式碼著色 (從 for 迴圈出發):
int i=0,a;
for(a=0;i<n;a++) {
if(a%3==2 && a%5==3 && a%7==2)
i++;
}
如果轉成 while 迴圈的話會變成這個樣子:
int i=0,a=0;
while (i<n) {
if(a%3==2 && a%5==3 && a%7==2)
i++;
a++;
}
有沒有發現這個 while 迴圈和你寫的不太一樣? 這個就是問題所在: 它們的結
構是不一樣的. 程式碼結構不同, 導致了求值順序甚至是語意的改變, 所以你
跑出來的結果才會有差. 為了驗證這件事情, 我們可以用簡易的方法來比較程
式碼結構: 將已經著色的程式碼區塊依照求值順序排成有多種顏色的線段, 然
後比較兩線段的顏色差異. 假設迴圈迭代 3 次, 你的 for 迴圈和 while 迴圈
畫成線段後會長成下面的樣子:
(for-loop)
(while-loop)
————————————————————————→
time
如上圖所示, 排出來的線段顏色相同, 才表示這兩份程式碼做的事情是等價的;
你的例子因為 a++ 和 if 語句 順序對調的緣故, 已經產生出不同的程式.
作者: Lipraxde (Lipraxde)   2020-09-16 23:10:00
其實就原 po 不熟悉 for 語法而已...
作者: kobe8112 (小B)   2020-09-16 23:45:00
這一篇文章值 392 Ptt幣 你贏了XDDD
作者: james732 (好人超)   2020-09-17 01:00:00
也太精美了 XD
作者: ckvir (ckvir)   2020-09-17 01:21:00
我覺得不需要把簡單問題複雜化 你這樣寫更難看的懂
作者: kaneson (Lance)   2020-09-17 06:57:00
我是覺得(3),(4)反過來就講完了,不過我喜歡樓主的(1)~(4)的說明方式
作者: derekjj (忘記帳號的男子)   2020-09-17 09:42:00
這個要給推,太神了
作者: v86861062 (數字人:3)   2020-09-17 10:31:00
讚哦
作者: jack82822005 (小郭郭)   2020-09-17 10:35:00
這篇文章賺喔XD
作者: GankTw (GankTw)   2020-09-17 12:21:00
推,分析的真好
作者: MOONRAKER (㊣牛鶴鰻毛人)   2020-09-17 12:42:00
作者: Kashir (Kashir)   2020-09-17 15:52:00
謝謝版大的精準分析!受益良多
作者: VSei (Chaos)   2020-09-17 17:13:00
分析透徹易懂,大推
作者: ggBird (ggBird)   2020-09-17 21:35:00
作者: FY4   2020-09-18 00:12:00
作者: annheilong (方格子)   2020-09-18 10:29:00
謝謝大大教我如何賺 P 幣XDDDD
作者: michael0728n (蒜˙遠古)   2020-09-18 14:17:00
這招酷喔推推
作者: VictorTom (鬼翼&娃娃魚)   2020-09-20 17:24:00
推精美:)
作者: eopXD (eopXD)   2020-09-22 17:24:00
推推
作者: stock999 (史托克柰褦錼)   2020-09-27 14:18:00
哪一種比較好呢??
作者: TuChinJui (Jerry)   2020-10-01 11:29:00
太強了,P幣大師4ni?

Links booklink

Contact Us: admin [ a t ] ucptt.com