1. 首頁
  2. 輔助設計與工程計算

C語言函式設計的一般原則和技巧

C語言函式設計的一般原則和技巧

C語言之所以命名為C,是因為 C語言源自Ken Thompson發明的B語言,而 B語言則源自BCPL語言。下面小編給大家介紹C語言函式設計的一般原則和技巧,歡迎閱讀!

C語言函式設計的一般原則和技巧

1、原則上儘量少使用全域性變數,因為全域性變數的生命週期太長,容易出錯,也會長時間佔用空間.各個原始檔負責本身檔案的全域性變數,同時提供一對對外函式,方便其它函式使用該函式來訪問變數。

比如:niSet_ValueName(…);niGet_ValueName(…);不要直接讀寫全域性變數,尤其是在多執行緒程式設計時,必須使用這種方式,並且對讀寫操作加鎖。

2、引數命名要恰當,順序要合理。

例如編寫字串複製函式str_copy,它有兩個引數。如果把引數名字起為str1 和str2,例如

void str_copy (char *str1, char *str2);

那麼我們很難搞清楚究竟是把str1 複製到str2 中,還是剛好倒過來。

可以把引數名字起得更有意義,如叫strSource 和strDestination。這樣從名字上就可以看出應該把strSource 複製到strDestination。

還有一個問題,這兩個引數那一個該在前那一個該在後?引數的順序要遵循程式設計師的習慣。一般地,應將目的引數放在前面,源引數放在後面。如果將函式宣告為:

void str_copy (char *strSource, char *strDestination);

別人在使用時可能會不假思索地寫成如下形式:

char str[20];

str_copy (str, “Hello World”); 引數順序顛倒

3、如果引數是指標,且僅作輸入引數用,則應在型別前加const,以防止該指標在函式體內被意外修改。例如:

void str_copy (char *strDestination,const char *strSource);

4、不要省略返回值的型別,如果函式沒有返回值,那麼應宣告為void 型別。

如果沒有返回值,編譯器則預設為函式的返回值是int型別的.。

5、在函式體的“入口處”,對引數的有效性進行檢查。尤其是指標引數,儘量使用assert宏做入口校驗,而不使用if語句校驗。(關於此問題討論,詳見指標與陣列那章。)

6、return 語句不可返回指向“棧記憶體”的“指標”,因為該記憶體在函式體結束時被自動銷燬。例如:

char * Func(void)

{

char str[30];

return str;

}

str 屬於區域性變數,位於棧記憶體中,在Func 結束的時候被釋放,所以返回str 將導致錯誤。

7、函式的功能要單一,不要設計多用途的函式。微軟的Win32 API就是違反本規則的典型,其函式往往因為引數不一樣而功能不一,導致很多初學者迷惑。

8、函式體的規模要小,儘量控制在80 行程式碼之內。

9、相同的輸入應當產生相同的輸出。儘量避免函式帶有“記憶”功能。

帶有“記憶”功能的函式,其行為可能是不可預測的,因為它的行為可能取決於某種“記憶狀態“。這樣的函式既不易理解又不利於測試和維護。在C 語言中,函式的static區域性變數是函式的“記憶”儲存器。建議儘量少用static 區域性變數,除非必需。

10、避免函式有太多的引數,引數個數儘量控制在4個或4個以內。如果引數太多,在使用時容易將引數型別或順序搞錯。微軟的Win32 API就是違反本規則的典型,其函式的引數往往七八個甚至十餘個。比如一個CreateWindow函式的引數就達11個之多。

11、儘量不要使用型別和數目不確定的引數。

C 標準庫函式printf 是採用不確定引數的典型代表,其原型為:

int printf(const chat *format[, argument]…);

這種風格的函式在編譯時喪失了嚴格的型別安全檢查。

12、有時候函式不需要返回值,但為了增加靈活性如支援鏈式表達,可以附加返回值。例如字串複製函式strcpy 的原型:

char *strcpy(char *strDest,const char *strSrc);

strcpy 函式將strSrc 複製至輸出引數strDest 中,同時函式的返回值又是strDest。這樣做並非多此一舉,可以獲得如下靈活性:

char str[20];

int length = strlen(strcpy(str, “Hello World”) );

13、不僅要檢查輸入引數的有效性,還要檢查透過其它途徑進入函式體內的變數的有效性,例如全域性變數、檔案控制代碼等。

14、函式名與返回值型別在語義上不可衝突。

違反這條規則的典型代表就是C語言標準庫函式getchar。幾乎沒有一部名著沒有提到getchar函式,因為它實在太經典,太容易讓人犯錯誤了。所以,每一個有經驗的作者都會拿這個例子來警示他的讀者,我這裡也是如此:

char c;

c = get);

if(EOF == c)

{

}

按照getchar 名字的意思,應該將變數c 定義為char 型別。但是很不幸,getchar 函式的返回值卻是int 型別,其原型為:

int getvoid);

由於c 是char 型別的,取值範圍是[-128,127],如果宏EOF 的值在char 的取值範圍之外,EOF 的值將無法全部儲存到c 內,會發生截斷,將EOF 值的低8 位儲存到c 裡。這樣if 語句有可能總是失敗。這種潛在的危險,如果不是犯過一次錯,肯怕很難發現。