學(xué)習(xí)嵌入式的同學(xué)應(yīng)該首先掌握嵌入式編碼規(guī)范,這樣才能更好的嵌入式系統(tǒng)。
下面就從這幾個(gè)方面講解一下嵌入式c編碼規(guī)范。
注釋風(fēng)格、排版風(fēng)格、頭文件風(fēng)格、變量定義、宏定義、函數(shù)
1 注釋風(fēng)格
1.1 注釋的原則是有助于對程序的閱讀和理解,注釋不宜太多也不能太少。注釋語言必須準(zhǔn)確、易懂、簡潔,沒有歧義性。
1.2 程序文件頭部代碼應(yīng)進(jìn)行注釋。注釋必須列出:版權(quán)說明、版本號、生成日期、作者、內(nèi)容、功能、與其他文件的關(guān)系、修改日志等。頭文件的注釋中還應(yīng)有函數(shù)功能簡要說明。
/*
* Copyright(C), 2007-2008, Red Hat Inc.
// 版權(quán)聲明
* File name:
// 文件名
* Author:
// 作者
* Version:
// 版本
* Date:
// 完成日期
* Deion:
// 描述本文件的功能,與其他模塊的關(guān)系
* Function List:
// 主要函數(shù)的列表,每條記錄應(yīng)包括函數(shù)名及功能簡要說明
* History:
// 修改歷史,包括每次修改的日期、修改者和修改內(nèi)容簡述
*/
1.3 函數(shù)頭部應(yīng)進(jìn)行注釋,列出函數(shù)的功能、輸入參數(shù)、輸出參數(shù)、返回值、調(diào)用關(guān)系等。
/*
* Function:
// 函數(shù)名稱
* Deion:
// 函數(shù)功能、性能等的描述
* Calls:
// 被本函數(shù)調(diào)用的函數(shù)清單
* Called By:
// 調(diào)用本函數(shù)的函數(shù)清單
* Input:
// 輸入?yún)?shù)說明,包括每個(gè)參數(shù)的作用
* Output:
// 輸出參數(shù)說明,有時(shí)通過指針參數(shù)返回一些變量值
* Return:
// 函數(shù)返回值的說明
* Others:
// 其他說明
*/
1.4 對于所有有特定含義的變量、常量、宏、結(jié)構(gòu)體等數(shù)據(jù)結(jié)構(gòu),如果其命名不是充分自注釋的,在聲明時(shí)都必須加上注釋,說明其實(shí)際含義。變量、常量、宏的注釋應(yīng)放在其上方或右方。
1.5 全局變量要有較詳細(xì)的注釋,包括功能,取值范圍,哪些函數(shù)訪問它,訪問時(shí)的注意事項(xiàng)。
1.6 為使程序排版整齊,方便閱讀和理解,注釋也要進(jìn)行縮進(jìn)和對齊。
void example_function( void )
{
/* comments one */
unsigned int min_port, max_port;
/* comments two */
if 。..
}
1.7 在復(fù)雜程序塊的結(jié)束行右方加注釋,以表明某程序塊的結(jié)束。
示例:
if (。..)
{
。..
while ( 。.. )
{
} /* while ( 。.. )循環(huán)語句結(jié)束*/
。..
} /* end of if (。..)語句結(jié)束 */
2 排版風(fēng)格
2.1 相對獨(dú)立的程序塊之間、變量聲明之后必須加空行。
int conn_fd;
int ret;
conn_fd = socket(AF_INET, SOCK_STREAM,0);
if (conn_fd 《 0) {
perror(“socket create”);
}
2.2 程序塊要采用縮進(jìn)風(fēng)格編寫,縮進(jìn)為4個(gè)空格或一個(gè)Tab鍵。
2.3 對于較長的語句(超過個(gè)80字符)要分成多行書寫,劃分出的新行要進(jìn)行適當(dāng)?shù)目s進(jìn),使排版整齊,語句可讀。對于參數(shù)較長的函數(shù)也要?jiǎng)澐殖啥嘈小?/p>
ret = connect(conn_fd, (struct sockaddr *)&serv_addr,
sizeof (struct sockaddr));
2.4 一行只寫一條語句,不允許把多個(gè)短語句寫在一行中。
以下語句是不規(guī)范的:
min_port = 1;
max_port = 65535;
應(yīng)該如下書寫:
min_port = 1;
max_port = 65535;
2.5 if、for、do、while、case、switch、default等語句各自占一行,且if、for、do、while等語句的執(zhí)行語句部分無論多少都要加括號{ }。
以下語句是不規(guī)范的:
if (conn_fd 《 0) perror(“socket create”);
應(yīng)該如下書寫:
if (conn_fd 《 0) {
perror(“socket create”);
}
2.6 ‘{’ 和 ‘}’ 要獨(dú)占一行
for (i=1; i《argc; i++)
{
。..
}
或者在代碼中‘{’與for語句同行,‘{’前面要有一個(gè)空格。
for (i=1; i《argc; i++) {
。..
}
2.7 空格的使用
(1)以下語句在逗號后面加空格。
int min_port, max_port;
(2)“+”、“-”、“*”、“=”等算術(shù)運(yùn)算符兩邊都有一個(gè)空格。
a = i + j;
(3)“《”、“》=”等比較操作符兩邊都有一個(gè)空格。
if (conn_fd 《 0) {
(4)“!”、“~”、“++”、“--”、“&”(地址運(yùn)算符)等單目操作符前后不加空格。
i++;
(5)“-》”、“。”前后不加空格。
portinfo.min_port = i * seg_len + 1;
3 變量定義
3.1 變量命名要清晰明了,有明確含義,同時(shí)使用完整的單詞或大家基本可以理解的縮寫,避免使人產(chǎn)生誤解。
示例:
temp可以簡寫為tmp
message可以簡寫為msg
3.2 對于變量命名,禁止使用單個(gè)字符(如i、j、k),建議除了要有具體含義外,還能表明其數(shù)據(jù)類型等,但i、j、k作為局部循環(huán)變量是允許的。
int iwidth;
// i表明該變量為int型,width指明是寬度
3.3 在Linux下變量命名一般是全小寫加下劃線的風(fēng)格。
一般使用:
int min_port;
一般不使用:
int minPort;
3.4 在多線程程序中使用全局變量,應(yīng)注意對變量操作的原子性。
3.5 應(yīng)避免局部變量與全局變量同名。
3.6 嚴(yán)禁使用未經(jīng)初始化的變量作為右值。在C程序中,引用未經(jīng)賦值的指針,經(jīng)常會(huì)引起程序崩潰。
以下代碼在Linux下將導(dǎo)致錯(cuò)誤,原因在于:沒有使p_string指向某個(gè)內(nèi)存空間的情況下,即對其進(jìn)行操作是錯(cuò)誤的。
char *p_string;
p_sting[0] = ‘a(chǎn)’;
應(yīng)先進(jìn)行初始化:
char *p_string;
p_string = (char *)malloc(BUFF_SIZE); // 這里假設(shè)BUFF_SIZE已定義
p_sting[0] = ‘a(chǎn)’;
4 宏定義
4.1 代碼中盡量少使用字面常量,而使用宏常量。
4.2 宏定義時(shí)宏名盡量大寫
4.3 如果宏名由多個(gè)單詞組成,那么個(gè)單詞中間要加_
#define BUFF_SIZE 1024
input_data = (char *)malloc(BUFF_SIZE);
4.4 用宏定義表達(dá)式時(shí),要使用完備的括號。
如下定義的宏存在一定的風(fēng)險(xiǎn):
#define GET_AREA(a,b) a*b
應(yīng)該定義為:
#define GET_AREA(a,b) ((a)*(b))
4.5 若宏中有多條語句,應(yīng)該將這些語句放在一對大括號中。
下面語句中只有宏的第一條表達(dá)式被執(zhí)行。
#define INTI_RECT_VALUE( a, b )\
a = 0;\
b = 0;
for (index = 0; index 《 RECT_TOTAL_NUM; index++)
INTI_RECT_VALUE( rect.a, rect.b );
正確的用法應(yīng)為:
#define INTI_RECT_VALUE( a, b ) {\
a = 0;\
b = 0;\
}
for (index = 0; index 《 RECT_TOTAL_NUM; index++) {
INTI_RECT_VALUE( rect[index].a, rect[index].b );
}
5函數(shù)定義
5.1 一個(gè)函數(shù)完成一個(gè)特定的功能,不應(yīng)嘗試在一個(gè)函數(shù)中實(shí)現(xiàn)多個(gè)不相關(guān)的功能。
5.2 檢查函數(shù)所有輸入?yún)?shù)的有效性,比如指針型參數(shù)要判斷是否為空,數(shù)組成員參數(shù)判斷是否越界。
5.3 一個(gè)函數(shù)的規(guī)模應(yīng)限制在200行以內(nèi)(不包括空行和注釋行)。
5.4 函數(shù)的功能應(yīng)該是可以預(yù)測的,也就是只要輸入數(shù)據(jù)相同就應(yīng)產(chǎn)生同樣的預(yù)期輸出。
5.5 函數(shù)的參數(shù)不宜過多,以1~3個(gè)為宜。
5.6 函數(shù)名應(yīng)準(zhǔn)確描述函數(shù)的功能,一般以動(dòng)詞加賓語的形式命名。
void print_record( struct *p_record, int record_len) ;
5.7 函數(shù)的返回值要清楚、明了,讓使用者不容易忽視錯(cuò)誤情況。函數(shù)的每種出錯(cuò)返回值的意義要清晰、明確,防止使用者誤用,理解錯(cuò)誤或忽視錯(cuò)誤返回碼。
5.8 如果多段代碼重復(fù)做同一件事情,那么應(yīng)該考慮把重復(fù)功能實(shí)現(xiàn)為一個(gè)函數(shù)。
5.9 減少函數(shù)本身或函數(shù)間的遞歸調(diào)用。
遞歸調(diào)用特別是函數(shù)間的遞歸調(diào)用(如A-》B-》C-》A),影響程序的可理解性;遞歸調(diào)用一般都占用較多的系統(tǒng)資源(如棧空間);遞歸調(diào)用對程序的測試不利。
6頭文件風(fēng)格
6.1 頭文件可保存如下內(nèi)容:宏定義、類型定義、結(jié)構(gòu)體定義、變量聲明、函數(shù)聲明
不要有如下內(nèi)容:變量定義、函數(shù)定義
6.2 頭文件必須要有重復(fù)包含限制
#ifndef _ALPS_H
#define _ALPS_H
#endif
責(zé)任編輯:ct
評論
查看更多