命名
函數(shù)命名:
C語言中,我們可以讓下劃線或者詞匯幫助我們表達(dá)函數(shù)功能:
set 可以表示設(shè)置一個(gè)參數(shù)為某值get 可以表示獲取某一個(gè)參數(shù)的值is 可以表示詢問是否是這種情況后綴:
max/min 可以表示某種操作的最大(小)次數(shù)cnt 可以表示當(dāng)前的操作次數(shù)key 某種關(guān)鍵值
size_t get_counts();
size_t retry_max();
int is_empty();
結(jié)構(gòu)體命名:
由于結(jié)構(gòu)體的 標(biāo)簽,不會(huì)污染命名,即標(biāo)簽不在命名搜索范圍之內(nèi),所以可以放心使用:
有人習(xí)慣使用 typedef, 而有人喜歡使用 struct tag obj,后者比較多,但是前者也不失為一種好方法,仁者見仁智者見智。
/*方法1*/
struct inetaddr_4{
int port;
char * name;
};
struct inetaddr_4 *addr_info;
/*方法2*/
typedef struct _addr{
int port;
char * name;
}inetaddr_4;
inetaddr_4 *addr_info_2;
兩者同處一個(gè)文件內(nèi)亦不會(huì)發(fā)生編譯錯(cuò)誤。
變量命名
_ 進(jìn)行輔助= 為標(biāo)準(zhǔn)進(jìn)行對(duì)齊等號(hào)左右兩端,最少有一個(gè)空格。
int main(void)
{
int counts = 0;
inetaddr_4 *addr = NULL;
return 0;
}
為了防止指針聲明定義時(shí)候出錯(cuò),將 * 緊貼著變量名總不會(huì)出錯(cuò)。
inetaddr_4 *addr, object, *addr_2;
其中 addr 和 addr_2 是指針,而 object 則是一個(gè)棧上的完整對(duì)象,并不是指針。
全局變量能少用就少用,必須要用的情況下,可以考慮添加前綴 g_
int g_counts;
#define 命名
_ 進(jìn)行分割如果多于一個(gè)語句,使用 do{...}while(0) 進(jìn)行包裹,防止 ; 錯(cuò)誤。
#define SWAP(x, y) \
do{ \
x = x + y; \
y = x - y; \
x = x - y; \
}while(0)
當(dāng)然這個(gè)交換宏實(shí)際上有一點(diǎn)缺陷,在大后方會(huì)提出。此處是代碼規(guī)范,就不重復(fù)強(qiáng)調(diào)。
enum 命名
_ 進(jìn)行分割define 相比,enum適用于同一類型的常量聲明,而不是單一獨(dú)立的常量。往往出現(xiàn)都是成組。格式化代碼
花括號(hào) {}
{} 進(jìn)行代碼包裹。{},有的人則習(xí)慣添加當(dāng)作用域超過一個(gè)屏幕的時(shí)候,可以適當(dāng)?shù)氖褂米⑨寔碇该?{} 作用域
while(1){
if(tmp == NULL){
break;
}
else if(fanny == 1){
... 大概超過了一個(gè)屏幕的代碼
} /*else if fanny*/
}/*end while*/
如果是代碼量少的情況下,但嵌套比較多,也可以使用這個(gè)方式進(jìn)行注釋。
括號(hào) ()
有人建議除了函數(shù)調(diào)用以外,在條件語句等類似情況下使用 () 要在關(guān)鍵字后空一格,再接上 ()語句,對(duì)于這一點(diǎn),我個(gè)人習(xí)慣是不空格,但總有這種說法。
if (space == NULL) {
/**TODO**/
}
while(1){
/**我習(xí)慣于如此寫**/
}
strcpy(str1, str2); /**第一種寫法是為了和函數(shù)調(diào)用寫法進(jìn)行區(qū)分**/
return 0;
switch
default 在最后,即使它永遠(yuǎn)不會(huì)用到。每個(gè) case 如果需要使用新變量,可以用 {} 包裹起來,并在里面完成所有操作。
switch(...)
{
case 1:
/**TODO**/
break;
case 2:
{
int new_vari;
/**創(chuàng)建新變量則用 {} 包裹起來**/
}
break;
default:
call_error();
}
goto
goto 關(guān)鍵字,而是使用 setjmp 和 longjmp來取代它,但是這還是那句話,仁者見仁智者見智,如果 goto 能夠讓代碼清晰,那何樂而不為呢,這個(gè)觀點(diǎn)也是最近才體會(huì)到的(并非我一己之言)。語句
頭文件保護(hù)
#include),如果缺少頭文件保護(hù),則會(huì)發(fā)生編譯錯(cuò)誤不要將 _ 作為宏的開頭或者結(jié)尾。
#ifndef VECTOR_H_INCLUDE
#define VECTOR_H_INCLUDE
/**TODO**/
#endif
宏
inline 函數(shù)來代替宏。在大后方會(huì)有解釋C11 中有一個(gè)新興的宏。變量
函數(shù)
如果某個(gè)循環(huán)帶著空語句,使用 {} 進(jìn)行掛載,以免出現(xiàn)意外。
while(*is_end++ != '\0')
{
;
}
雖然是空的循環(huán)體,但是寫出來以免造成誤循環(huán)。
盡量不要讓函數(shù)返回值直接作為條件語句的判斷,這樣會(huì)極大降低可讀性
if(is_eof(file) == 0)
好過
if(!is_eof(file))
不要為了方便或者一點(diǎn)點(diǎn)的所謂速度提升(也許根本沒有),而放棄可讀性,使用嵌入式的賦值語句
int add = 10;
int num = 11;
int thr = 20;
add = add + thr;
num = add + 20;
不要寫成
num = (add = add + thr) + 20;
#if 而不是 #ifdef可以使用 define() 來代替 #ifdef的功能
#if !define(USERS_DEFINE)
#define USERS_DEFINE ...
#endif
對(duì)于某些大段需要消除的代碼,我們不能使用注釋 /**/,因?yàn)樽⑨尣荒軆?nèi)嵌著注釋(//除外),我們可以使用黑魔法:
#if NOT_DECLARATION
/**想要注釋的代碼**/
#endif
#define 給它一個(gè)名字,來說明這個(gè)數(shù)字的意義。