C++程序員的自我修養(5)

軟件特攻隊|C/C++程序員的自我修養(5)

什麼是好的程序員?是不是懂得很多技術細節?還是懂底層編程?還是編程速度比較快?我覺得都不是。對於一些技術細節來說和底層的技術,只要看幫助,查資料就能找到,對於速度快,只要編得多也就熟能生巧了。

如果要了解一個程序員,我想首先最想看的就是他的程序代碼,程序代碼可以看出一個程序員的素質和修養,程序就像一個作品,有素質有修養的程序員的作品必然是一圖精美的圖畫,一首美妙的歌曲,一本賞心悅目的小說。

“細微之處見真功”,真正能體現一個程序的功底恰恰在這些細微之處。

這就是程序員的——編程修養。我總結了在用C/C++語言(主要是C語言)進行程序寫作上的三十二個“修養”,通過這些,你可以寫出質量高的程序,同時也會讓看你程序的人漬漬稱道,那些看過你程序的人一定會說:“這個人的編程修養不錯”。

21、goto語句的使用

N年前,軟件開發的一代宗師——迪傑斯特拉(Dijkstra)說過:“goto statment is harmful !!”,並建議取消goto語句。因為goto語句不利於程序代碼的維護性。

這裡我也強烈建議不要使用goto語句,除非下面的這種情況:

#define FREE(p) if(p) { \\

free(p); \\

p = NULL; \\

}

main()

{

char *fname=NULL, *lname=NULL, *mname=NULL;

fname = ( char* ) calloc ( 20, sizeof(char) );

if ( fname == NULL ){

goto ErrHandle;

}

lname = ( char* ) calloc ( 20, sizeof(char) );

if ( lname == NULL ){

goto ErrHandle;

}

mname = ( char* ) calloc ( 20, sizeof(char) );

if ( mname == NULL ){

goto ErrHandle;

}

......

ErrHandle:

FREE(fname);

FREE(lname);

FREE(mname);

ReportError(ERR_NO_MEMOEY);

}

也只有在這種情況下,goto語句會讓你的程序更易讀,更容易維護。(在用嵌C來對數據庫設置遊標操作時,或是對數據庫建立鏈接時,也會遇到這種結構)

22、宏的使用

很多程序員不知道C中的“宏”到底是什麼意思?特別是當宏有參數的時候,經常把宏和函數混淆。我想在這裡我還是先講講“宏”,宏只是一種定義,他定義了一個語句塊,當程序編譯時,編譯器首先要執行一個“替換”源程序的動作,把宏引用的地方替換成宏定義的語句塊,就像文本文件替換一樣。這個動作術語叫“宏的展開”

使用宏是比較“危險”的,因為你不知道宏展開後會是什麼一個樣子。例如下面這個宏:

#define MAX(a, b) a>b?a:b

當我們這樣使用宏時,沒有什麼問題:MAX( num1, num2 ); 因為宏展開後變成 num1>num2?num1:num2;。但是,如果是這樣調用的,MAX( 17+32, 25+21 ); 呢,編譯時出現錯誤,原因是,宏展開後變成:17+32>25+21?17+32:25+21,哇,這是什麼啊?

所以,宏在使用時,參數一定要加上括號,上述的那個例子改成如下所示就能解決問題了。

#define MAX( (a), (b) ) (a)>(b)?(a):(b)

即使是這樣,也不這個宏也還是有Bug,因為如果我這樣調用 MAX(i++, j++); , 經過這個宏以後,i和j都被累加了兩次,這絕不是我們想要的。

所以,在宏的使用上還是要謹慎考慮,因為宏展開是的結果是很難讓人預料的。而且雖然,宏的執行很快(因為沒有函數調用的開銷),但宏會讓源代碼澎漲,使目標文件尺寸變大,(如:一個50行的宏,程序中有1000個地方用到,宏展開後會很不得了),相反不能讓程序執行得更快(因為執行文件變大,運行時系統換頁頻繁)。

因此,在決定是用函數,還是用宏時得要小心。

23、static的使用

static關鍵字,表示了“靜態”,一般來說,他會被經常用於變量和函數。一個static的變量,其實就是全局變量,只不過他是有作用域的全局變量。比如一個函數中的static變量:

char*
getConsumerName()
{
static int cnt = 0;

....
cnt++;
....
}

cnt變量的值會跟隨著函數的調用次而遞增,函數退出後,cnt的值還存在,只是cnt只能在函數中才能被訪問。而cnt的內存也只會在函數第一次被調用時才會被分配和初始化,以後每次進入函數,都不為static分配了,而直接使用上一次的值。

對於一些被經常調用的函數內的常量,最好也聲明成static(參見第12條)

但static的最多的用處卻不在這裡,其最大的作用的控制訪問,在C中如果一個函數或是一個全局變量被聲明為static,那麼,這個函數和這個全局變量,將只能在這個C文件中被訪問,如果別的C文件中調用這個C文件中的函數,或是使用其中的全局(用extern關鍵字),將會發生鏈接時錯誤。這個特性可以用於數據和程序保密。

24、函數中的代碼尺寸

一個函數完成一個具體的功能,一般來說,一個函數中的代碼最好不要超過600行左右,越少越好,最好的函數一般在100行以內,300行左右的孫函數就差不多了。有證據表明,一個函數中的代碼如果超過500行,就會有和別的函數相同或是相近的代碼,也就是說,就可以再寫另一個函數。

另外,函數一般是完成一個特定的功能,千萬忌諱在一個函數中做許多件不同的事。函數的功能越單一越好,一方面有利於函數的易讀性,另一方面更有利於代碼的維護和重用,功能越單一表示這個函數就越可能給更多的程序提供服務,也就是說共性就越多。

雖然函數的調用會有一定的開銷,但比起軟件後期維護來說,增加一些運行時的開銷而換來更好的可維護性和代碼重用性,是很值得的一件事。


分享到:


相關文章: