嵌入式c語言編碼規范


學習嵌入式的同學應該首先掌握嵌入式編碼規范,這樣才能更好的嵌入式系統。

下面就從這幾個方面講解一下嵌入式c編碼規范。

注釋風格、排版風格、頭文件風格、變量定義、宏定義、函數

 

1 注釋風格

1.1  注釋的原則是有助於對程序的閱讀和理解,注釋不宜太多也不能太少。注釋語言必須准確、易懂、簡潔,沒有歧義性。

1.2  程序文件頭部代碼應進行注釋。注釋必須列出:版權說明、版本號、生成日期、作者、內容、功能、與其他文件的關系、修改日志等。頭文件的注釋中還應有函數功能簡要說明。

/*

* Copyright(C), 2007-2008, Red Hat Inc. // 版權聲明

* File name: // 文件名

* Author:      // 作者

* Version:    // 版本

* Date: // 完成日期

* Description: // 描述本文件的功能,與其他模塊的關系

* Function List: // 主要函數的列表,每條記錄應包括函數名及功能簡要說明

* History:    // 修改歷史,包括每次修改的日期、修改者和修改內容簡述

*/

1.3  函數頭部應進行注釋,列出函數的功能、輸入參數、輸出參數、返回值、調用關系等。

/*

* Function:      // 函數名稱

* Description:    // 函數功能、性能等的描述

* Calls:      // 被本函數調用的函數清單

* Called By:      // 調用本函數的函數清單

* Input:          // 輸入參數說明,包括每個參數的作用

* Output:        // 輸出參數說明,有時通過指針參數返回一些變量值

* Return:          // 函數返回值的說明

* Others:        // 其他說明

*/

1.4  對於所有有特定含義的變量、常量、宏、結構體等數據結構,如果其命名不是充分自注釋的,在聲明時都必須加上注釋,說明其實際含義。變量、常量、宏的注釋應放在其上方或右方。

1.5  全局變量要有較詳細的注釋,包括功能,取值范圍,哪些函數訪問它,訪問時的注意事項。

1.6  為使程序排版整齊,方便閱讀和理解,注釋也要進行縮進和對齊。

void example_function( void )

{

     /* comments one */

     unsigned int min_port, max_port;

          

     /* comments two */

     if ...

}

1.7  在復雜程序塊的結束行右方加注釋,以表明某程序塊的結束。

示例:

if (...)

{

    ...

     

    while ( ... )

    {

      ...

    } /* while ( ... )循環語句結束*/

     ...

     

} /* end of  if (...)語句結束 */ 

 

2 排版風格

2.1  相對獨立的程序塊之間、變量聲明之后必須加空行。

int          conn_fd;

int          ret;

     

conn_fd = socket(AF_INET, SOCK_STREAM,0);

if (conn_fd < 0) {

    perror("socket create");

}

2.2  程序塊要采用縮進風格編寫,縮進為4個空格或一個Tab鍵。

2.3  對於較長的語句(超過個80字符)要分成多行書寫,划分出的新行要進行適當的縮進,使排版整齊,語句可讀。對於參數較長的函數也要划分成多行。

ret = connect(conn_fd, (struct sockaddr *)&serv_addr, 

                  sizeof (struct sockaddr));

2.4  一行只寫一條語句,不允許把多個短語句寫在一行中。

以下語句是不規范的:

min_port = 1; max_port = 65535;

應該如下書寫:

min_port = 1;

max_port = 65535;

2.5  if、for、do、while、case、switch、default等語句各自占一行,且if、for、do、while等語句的執行語句部分無論多少都要加括號{ }。

以下語句是不規范的:

if (conn_fd < 0) perror("socket create");

應該如下書寫:

if (conn_fd < 0) {

     perror("socket create");

}

2.6  ‘{’  和 ‘}’ 要獨占一行

for (i=1; i<argc; i++)

{

     ...

}

或者在代碼中‘{’與for語句同行,‘{’前面要有一個空格。

for (i=1; i<argc; i++) {

     ...

}

2.7  空格的使用

(1)以下語句在逗號后面加空格。

     int min_port, max_port;

(2)"+"、"-"、"*"、"="等算術運算符兩邊都有一個空格。

     a = i + j;

(3)"<"、">="等比較操作符兩邊都有一個空格。

     if (conn_fd < 0) {

(4)"!"、"~"、"++"、"--"、"&"(地址運算符)等單目操作符前后不加空格。

     i++;

(5)"->"、"."前后不加空格。

     portinfo.min_port = i * seg_len + 1;

 

3 變量定義

3.1  變量命名要清晰明了,有明確含義,同時使用完整的單詞或大家基本可以理解的縮寫,避免使人產生誤解。

示例:

temp可以簡寫為tmp

message可以簡寫為msg

3.2  對於變量命名,禁止使用單個字符(如i、j、k),建議除了要有具體含義外,還能表明其數據類型等,但i、j、k作為局部循環變量是允許的。

int iwidth; // i表明該變量為int型,width指明是寬度

3.3  在Linux下變量命名一般是全小寫加下划線的風格。

一般使用:

int min_port;

一般不使用:

int minPort;

3.4  在多線程程序中使用全局變量,應注意對變量操作的原子性。

3.5  應避免局部變量與全局變量同名。

3.6  嚴禁使用未經初始化的變量作為右值。在C程序中,引用未經賦值的指針,經常會引起程序崩潰。

以下代碼在Linux下將導致錯誤,原因在於:沒有使p_string指向某個內存空間的情況下,即對其進行操作是錯誤的。

char *p_string;

p_sting[0] = ‘a’;

應先進行初始化:

char *p_string;

p_string = (char *)malloc(BUFF_SIZE);          // 這里假設BUFF_SIZE已定義

p_sting[0] = ‘a’;     

4 宏定義

4.1  代碼中盡量少使用字面常量,而使用宏常量。

4.2  宏定義時宏名盡量大寫

4.3  如果宏名由多個單詞組成,那么個單詞中間要加_

#define BUFF_SIZE          1024

input_data = (char *)malloc(BUFF_SIZE);

 

4.4  用宏定義表達式時,要使用完備的括號。

如下定義的宏存在一定的風險:

#define GET_AREA(a,b)     a*b

應該定義為:

#define GET_AREA(a,b)     ((a)*(b))

4.5  若宏中有多條語句,應該將這些語句放在一對大括號中。

下面語句中只有宏的第一條表達式被執行。

#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 );

正確的用法應為:

#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函數定義

5.1  一個函數完成一個特定的功能,不應嘗試在一個函數中實現多個不相關的功能。

5.2  檢查函數所有輸入參數的有效性,比如指針型參數要判斷是否為空,數組成員參數判斷是否越界。

5.3  一個函數的規模應限制在200行以內(不包括空行和注釋行)。

5.4  函數的功能應該是可以預測的,也就是只要輸入數據相同就應產生同樣的預期輸出。

5.5  函數的參數不宜過多,以1~3個為宜。

5.6  函數名應准確描述函數的功能,一般以動詞加賓語的形式命名。

void print_record( struct *p_record, int record_len) ;

5.7  函數的返回值要清楚、明了,讓使用者不容易忽視錯誤情況。函數的每種出錯返回值的意義要清晰、明確,防止使用者誤用,理解錯誤或忽視錯誤返回碼。

5.8  如果多段代碼重復做同一件事情,那么應該考慮把重復功能實現為一個函數。

5.9  減少函數本身或函數間的遞歸調用。

遞歸調用特別是函數間的遞歸調用(如A->B->C->A),影響程序的可理解性;遞歸調用一般都占用較多的系統資源(如棧空間);遞歸調用對程序的測試不利。

6頭文件風格

6.1 頭文件可保存如下內容:宏定義、類型定義、結構體定義、變量聲明、函數聲明

    不要有如下內容:變量定義、函數定義

6.2 頭文件必須要有重復包含限制

#ifndef _ALPS_H

#define _ALPS_H

...

#endif


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM