2014年1月9日 星期四

C語言很容易藏bug

今天 trace 學生寫的 C 程式碼,發現學生犯了一個嚴重的錯誤。我用下面這個例子說明:

int i;
for (i = 0; i < 10, i != 3, i != 5; i++)
   printf("%d ", i);


學生的想法是印出除了 3 與 5 外所有 0 到 9 之間的整數。C 語言允許這樣寫,但結果不是學生所想的那樣子。上面程式的執行結果會是

0 1 2 3 4

原因我用下面這句英文來解釋。

The value of a multiple-statement expression is the value of the last statement in the expression.

後來學生送來更正後的版本,意思就像下面的程式碼:

int i;
for (i = 0; i < 10 && i != 3 && i != 5; i++)
   printf("%d ", i);


雖然更正了誤將逗號當 and 用的錯誤,這個版本仍然不會印出除了 3 與 5 外所有 0 到 9 之間的整數。執行結果如下:

 0 1 2

原因出在紅色字體部分是 C 語言迴圈繼續執行的條件,而非每次 iteration 中是否要執行 loop body 的條件。一旦這個條件不滿足,迴圈就結束了,而非只是 skip 此次 iteration。