2008年10月31日 星期五

程式碼是給人讀的

不是給機器看的。

Code Complete書裡面如是說。

這本書,繁體中文的書名叫做「軟體建構之道」,大陸那邊就照字面翻譯,叫做「代碼大全」。就像電影"The Day After Tomorrow”,一邊是比較有意境的「明天過後」,另一邊是標準翻譯的「後天」。

好,閒話不講。

最近玩了幾天反組譯工具程式,複習組合語言的時候,突然想到這句話。

然後想到我一直把它當作是程式碼的「文言文」的這個語法:

int a1=rand()%20;
int a2;
a2 = (a1>10)? (a1-10):(a1+10);

這段程式,我寧願把它寫的比較「白話」一點:

int a1=rand()%20;
int a2;
if (a1>10)
{
    a2=a1-10;
}
else
{
    a2=a1+10;
}

你說,為什麼一行可以寫完的東西偏偏要改成多了幾行? 我說,因為容易看懂。

另一個原因,容易Trace Bug。第一個code sample裡,你怎麼trace? 怎麼做中斷? 怎麼知道這個條件究竟有沒有成立?

更不要說我常常忘記究竟是問號還是冒號放前面,究竟是 true : false 還是 false : true。

第二個code sample裡,你就絕對不會誤解我要表達的程式意義,我也絕對不會懷疑我是不是又把 true, false寫反了。

至於給機器看的是什麼? 第一段程式編譯出來的結果是這樣:

; 50   :     a2 = (a1>10)? (a1-10):(a1+10);
  000d7    83 7d fc 0a     cmp     DWORD PTR _a1$[ebp], 10    ; 0000000aH
  000db    7e 0b         jle     SHORT $LN9@wmain
  000dd    8b 55 fc     mov     edx, DWORD PTR _a1$[ebp]
  000e0    83 ea 0a     sub     edx, 10            ; 0000000aH
  000e3    89 55 c4     mov     DWORD PTR tv69[ebp], edx
  000e6    eb 09         jmp     SHORT $LN10@wmain
$LN9@wmain:
  000e8    8b 45 fc     mov     eax, DWORD PTR _a1$[ebp]
  000eb    83 c0 0a     add     eax, 10            ; 0000000aH
  000ee    89 45 c4     mov     DWORD PTR tv69[ebp], eax
$LN10@wmain:
  000f1    8b 4d c4     mov     ecx, DWORD PTR tv69[ebp]
  000f4    89 4d f8     mov     DWORD PTR _a2$[ebp], ecx

 

而第二段程式碼編譯出來的結果,像這樣:

; 50   :     if (a1>10)
  000d7    83 7d fc 0a     cmp     DWORD PTR _a1$[ebp], 10    ; 0000000aH
  000db    7e 0b         jle     SHORT $LN8@wmain
; 51   :     {
; 52   :         a2=a1-10;
  000dd    8b 55 fc     mov     edx, DWORD PTR _a1$[ebp]
  000e0    83 ea 0a     sub     edx, 10            ; 0000000aH
  000e3    89 55 f8     mov     DWORD PTR _a2$[ebp], edx
; 53   :     }
; 54   :     else
  000e6    eb 09         jmp     SHORT $LN7@wmain
$LN8@wmain:
; 55   :     {
; 56   :         a2=a1+10;
  000e8    8b 45 fc     mov     eax, DWORD PTR _a1$[ebp]
  000eb    83 c0 0a     add     eax, 10            ; 0000000aH
  000ee    89 45 f8     mov     DWORD PTR _a2$[ebp], eax
$LN7@wmain:
; 57   :     }

 

仔細看,文言文跟白話文的兩段程式碼,是一樣的作用,所以編譯出來的結果當然也是一樣的。既然是相同的,那為什麼不寫得讓人容易看懂些?

沒有留言: