前幾天看別人的代碼,真是的看的頭昏腦漲,基本沒有注釋、亂起的變量名字,還要費盡心思去解讀作者的意思。突然感覺高效的程序注釋說明和良好的編程風格是多么的重要。
為了不讓別人在看到我的代碼時在背后罵我,也為了更高效持久的開發,我想也應該是時候特別規定一下自己的編程風格了。
1、文件/文件夾命名
文件命名要精確,文件名要准確反映文件內容。
文件命名一律使用小寫字母,如keyboard.c。
如有縮寫單詞,則必須大寫,如flash_LED.c、UART.c。其中LED是Light-Emitting Diode(發光二極管)的縮寫,UART是Universal Asynchronous Receiver/Transmitter(通用異步收發器,也就是串口)的縮寫。對於有約定俗成縮寫的單詞,就使用縮寫詞匯。
文件名應使用名詞,而不應該使用動詞。如果文件內容是數據采集,應該命名為data_collection.c而非data_collect.c。
2、標識符命名
C語言中,可以定義各種標識符作為變量名、數組名、函數名、標號及用戶定義對象的名稱。ANSI C規定標識符必須由字母和下划線開始,隨后可以出現字母、下划線和數字。
1)變量命名
變量命名一律小寫,縮寫詞匯用大寫,且全部使用名詞,可以使用形容詞修飾,用“_”表從屬關系。因為變量名作為一個變量的名字,就應該是一個名詞。
局部循環體控制變量用i,j,k。如for(i=0;i<100;i++)。
指針變量用“p_”開頭,后面接指向內容。如指向高度變量的指針,命名為“*p_height”。請讀者自行區分指針和指針變量的區別。
局部變量盡量用一個單詞表達清其含義。
全局變量命名時首先寫所屬模塊名稱。例如如一個傳感器文件sensor.c里面的一個全局變量要代表溫度,則命名為sensor_temperature。又例如LCD(液晶顯示屏)文件LCD.c中表示LCD狀態的全局變量命名為LCD_status。因為全局變量往往跨文件調用,如不寫清變量定義位置,當程序龐大,而IDE又不支持一鍵定位時,查找起來很麻煩。即使IDE支持一鍵定位,一個清楚明白的命名,能讓人瞬間讀懂該變量的含義。
2)數組命名
數組命名各單詞首字母大寫,其他同變量。
讀者可能會有疑問,數組名后面會有[]符號,與變量區別明顯,為什么要用首字母大寫的方式。實際上,在數組名作為實參傳遞數組首地址時,往往會省略[]符號,應該數組名就是數組的首地址。例如:
unsigned char string[]=”abcdefg”;
printf(“%s”,string);
在以上代碼中,string是一個8位數組(為什么是8位?),在使用printf()函數輸出時,只寫了數組名,顯然這種方式是被允許的。而此時就沒有寫[],在這種情況下,並不能瞬間知道string是變量還是數組,而需要參考前面的格式控制符“%s”。在其他函數中,或許沒有“%s”這樣的格式控制符幫助我們判斷string到底是數組還是變量,我們只有找到函數的聲明或定義才能知道答案,嚴重影響閱讀。因此有必要對數組和變量加以區分。
3)函數命名
函數命名各單詞首字母大寫,寫成主謂語形式,主語用名詞,謂語用動詞,縮寫詞匯用大寫,用“_”表從屬關系。主語通常為模塊名,而謂語是描述模塊的動作。因為函數本身就是用來執行一系列的動作的, 結合函數參數,可以表達通順的語句。舉個簡單的例子:延時函數。定義一個ms級延時函數為:
void Delay(unsigned int ms);
當然,函數命名中必要時可以出現賓語。這種情況多出現在函數沒有參數的情況下。如一個函數的功能是LCD顯示時間,而時間是全局變量,因此這個函數就不需要參數,此時直接定義成void LCD_Display_Time(void)(其實是聲明,因為沒寫函數體)。
4)標號命名
由於在硬件編程中標號可以用循環來代替,所以很少用到。我們規定標號的命名格式基本同變量,使用全部小寫的名詞,但是只用一個單詞表示即可。因為標號時候的時候或者前面加了goto,或者后面加了“:”,很容易與變量區分開。況且只是一個定位標志,所以一個單詞足夠了。
5)自定義類型命名
自定義類型命名主要指使用typedef定義的新類型名,以及結構體類型、共用體類型的類型名(而非該類型的變量名)。
自定義的新類型名,只用一個單詞,首字母大寫。但是定義這種新類型的變量時,命名規則與變量命名規則完全相同。
請自行體會新類型名與新類型變量的區別。
6)宏定義命名
宏定義命名全部使用大寫字母,單詞數不限。可以加入數字和下划線,但是數字不能開頭 。
由於宏定義的特殊性,對其使用名詞或動詞不作規定。因為宏定義一個函數時,應該是動詞性質,而宏定義一個常數時,應該是名詞性質。
3、表達式的書寫
操作數與運算符之間要有空格隔開,以便於區分。
4、文件編寫
(1)、文件按模塊划分,函數按功能划分。
(2)、
源文件(.c) |
頭文件(.h) |
頭文件包含指令(#include) |
頭文件包含指令(#include) |
|
宏定義(#define) |
所有函數定義(必須有函數體,即{ }) 內部函數聲明(static,不能有函數體) |
外部函數聲明(extern,不能有函數體) |
外部變量定義(必須賦初值) 靜態外部變量定義(static,必須賦初值) |
外部變量聲明(extern,不能賦值)
|
|
自定義類型(typedef) |
外部數組定義 靜態內部數組定義(static) |
外部數組聲明(const) |
條件編譯 |
條件編譯 |
由上表可以看出,h文件內存放的都是對外可見的變量、函數數組等的聲明,宏定義則是對內對外都可以使用,放在這里主要為了修改方便。
在定義外部變量、數組和函數時,不需要寫extern,因為缺省時默認extern。而聲明外部變量、數組和函數時,必須用extern顯式聲明,這樣是為了讓代碼更直觀。
(3)、函數頭部注釋格式
/********************************************************
*名 稱: function(int par)
*功 能:**
*入口參數:**
*出口參數:**
*說 明:
********************************************************/
借鑒了一些良好的編程風格:http://www.cnblogs.com/foxsay/p/5331388.html