《卓越程式設計師密碼》讀後感

黃志斌發表於2013-02-28

今年春節期間,我在圖靈社群購買了三本電子書,其中一本是《卓越程式設計師密碼》。這本書不厚,正文才158頁。閱讀過程也很輕鬆。

作者張家為(Ka Wai Cheung)先生在中文版序中說:

在程式設計的世界裡,我們會和各種各樣的“語言”打交道。雖然我主要的伺服器端開發語言是C#,但我的工作方法卻幾乎可以完全應用到Java、PHP、Ruby或Python上。程式語言雖有不同,核心的程式設計思想、方法和架構卻是高度類似的。我們只是用不同的方式來表達而已。

正好我目前主要也使用 C# 語言,興趣相投。我最初接觸計算機時學的是 PASCAL 語言。第二門語言是 C 語言,讀的是經典的 K&R 的《C程式設計語言》,當時還是第一版。以後逐漸學習了 C++ 語言。現在全面轉向 C# 語言,而且對 Linux 作業系統下的 Mono 很有興趣。

《卓越程式設計師密碼》由 50 篇短小精悍的文章組成。在閱讀過程中,很多話題都能引起我的會心一笑。比如第 30 篇談到為電梯設計軟體,要求要讓人們呆在電梯裡的總時間最短。這個目標是非常難以實現的,而且還是沒有什麼回報的複雜性,這就是一個難編就意味著難用的例子。傳統的電梯演算法既簡單,又好用。

在第 47 篇“程式碼是最好的初級程式設計師”中,作者給出了一個 C# 程式的程式碼片段:

public int sum_range_of_positive_integers_to_100()
{
     int sum;

     for (int i = 1; i <= 100; i++)
     {
         sum += i;
     }

     return sum;
}

這段程式碼用來計算從 1 加到 100 得多少。但是這段程式碼是有問題的,使用 C# 編譯器編譯時會報告以下錯誤:

error CS0165: Use of unassigned local variable `sum'

這種區域性變數未初始化的情況是初學者很容易犯的錯誤,作者在這裡也粗心了。還好 C# 編譯器會幫助我們避免這種錯誤。
如果是 C 語言,就沒這麼幸運了,編譯會通過,但執行結果很可能就不正確了。還好,有個 splint 工具也可以幫助我們:

Splint is a tool for statically checking C programs for security vulnerabilities and coding mistakes.

假設我們有以下 C 語言程式:

#include <stdio.h>

int main()
{
  int sum;
  printf("%d\n", sum);
  return 0;
}

在 Arch Linux 作業系統中,使用 gcc 編譯,再使用 splint 工具檢查,結果如下:

work$ gcc a.c && ./a.out
0
work$ splint a.c
Splint 3.1.2 --- 14 Sep 2011

a.c: (in function main)
a.c:6:18: Variable sum used before definition
  An rvalue is used that may not be initialized to a value on some execution
  path. (Use -usedef to inhibit warning)

Finished checking --- 1 code warning

C 編譯器一聲不吭,而 splint 就報告可能存在問題。

C# 語言規範5.1.7 Local variables 中提到:

A local variable introduced by a local-variable-declaration is not automatically initialized and thus has no default value.

對於 C 語言來說,在 K&R 的經典著作 《C程式設計語言》(第二版)APPENDIX A: Reference ManualA8.7 Initialization 中提到:

The initial value of an automatic object not explicitly initialized is undefined.

從上面的權威資料中可以看出,無論是 C 語言,還是 C# 語言,區域性變數不初始化是不行的。

此外,我還給《卓越程式設計師密碼》提了不少勘誤,有些已經被圖靈社群的編輯確認了,但還有些至今還沒有處理。

相關文章