嵌入式 C 編碼風格

嵌入式 C 編碼風格

版本 日期 作者 備註
V1.0 2019.09.16 Like Shadows 初版

文件頭

  • 所有新建的文件,都必須在最開始聲明 Project 的許可條款。

  • 對於從其它地方拷貝的文件,如果有許可條款聲明,則應保留。

    Project 的許可條款示例如下:

    /*
     * Copyright [2019] [xxxx Co., Ltd]
     * 
     * Licensed under the Apache License, Version 2.0 (the "License"),
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     * 
     * 		http://www.xxxx.com
     *
     * Unless required by applicable law or agreed to in writing,
     * software distributed under the License is distributed on an
     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     * KIND, either express or implied.  See the License for the
     * specific language governing permissions and limitations
     * under the License.
     */
    

空格和括號

  • 代碼必須以 4 字節縮進,不建議採用 TAB 縮進。

  • 不允許在行尾添加空格。

  • 關鍵字後面需要添加空格 (如:for,if,return,switch,while)。

  • for,else,if,while,表達式必須使用大括號

    //正確
    if (x) {
        assert(0);
    } else {
        assert(0);
    }
    
    
    //錯誤
    if (x)
        assert(0);
    else
        assert(0);
    
  • 表達式的括號必須與表達式位於同一行。

    //正確
    for (i = 0; i < 10; i ++) {
        if (i == 5) {
            break;
        } else {
            continue;
        }
    }
    
    //錯誤
    for (i = 0; i < 10; i ++) 
    {
        if (i == 5) {
            break;
        } 
        else {
            continue;
        }
    }
    
  • 函數聲明之後,括號必須位於下一行的起始位置。

    //正確
    static void *
    function(int var1, int var2)
    {
        
    }
    
    //錯誤
    static void *
    function(int var1, int var2) {
    
    }
    

行長度和換行規則

  • 每行最長不應該超過 79 字符長度。

  • 當需要換行封裝表達式時,操作符應位於行尾。

    //正確
    if (x && 
        y == 10 &&
        b)
        
    //錯誤
    if (x
    	&& y == 10
        && b)
    

註釋

  • 註釋 文件頭

    /**
     * @file xxx.h
     * @brief 文件簡單概述
     *
     * 詳細概述
     *
     * @author 作者
     * @version 版本號(maj.min 主版本.次版本格式)
     * @date 日期
     */
    
  • 註釋 函數

    /**
     * @brief 函數的簡單概述
     * @return 函數返回值,不同值表示的含義
     * @note 函數需要注意的事項
     * @param para1 IN/OUT	參數 para1 是輸入輸出參數
     * @param para2 IN		參數 para2 是輸入參數
     */
    
  • 註釋 變量/枚舉

    int a;   ///< 變量 a 的說明
    
    
    /// @brief xxx 枚舉變量的簡要說明
    ///
    /// xxx 枚舉變量的詳細說明,枚舉變量的詳細說明和函數的說明寫法一致,
    /// 每個枚舉變量可以進行單獨說明
    enum {
        em1,  ///< 枚舉值 em1 的說明
        em2
    };
    
  • 所有的公用 APIs 的註釋必須使用 Doxygen 的註釋規範來描述目的,參數和返回值等等。私有 APIs 則不需要。

頭文件

  • 頭文件必須包含以下結構:

    • Project 的許可條款 (參見文件頭部分)。
    • #ifdef,用於防止多重包含。
    • #include,用於引用要求包含的其他頭文件。
    • #ifdef __cplusplus,用於爲 C++ 封裝友好的 APIs
    • 頭文件的內容。
    • #ifdef,將使用以下格式,如果目錄名爲 os,文件名爲 callout.h,則定義如下:
    ```c
    #ifndef _OS_CALLOUT_H
    #define _OS_CALLOUT_H
    ...
    #endif  
    ```
    
  • #include,必須位於 #ifdef __cplusplus之前。

  • cplusplus必須使用以下格式,並且位於頭文件內容之前。

    #ifdef __cplusplus
    extern "C" {
    #endif
        
    ... /* content */
        
    #ifdef __cplusplus
    }
    #endif   
    

命名

  • 函數,結構體和變量的名稱必須全部小寫。

  • 名稱應該儘可能的短,但也不能太短。

  • 全局可見的名稱應該加上模塊名稱作爲前綴,並以_相連接。

    /* os 爲模塊名, callout_int 爲函數名 */
    
    //正確
    os_callout_int(&c);
    
    //錯誤
    callout_int(&c);
    

函數

  • 函數調用時,函數名後面不能有空格。

    //正確
    rc = function(a);
    
    //錯誤
    rc = function (a);
    
  • 函數的參數見應使用 ,和空格分隔開來。

    //正確
    rc = function(a, b);
    
    //錯誤
    rc = function(a,b);
    
  • 函數類型應位於函數名的上一行,並獨佔一行。

    //正確
    static void *
    function(int var1, int var2)
    {
        
    }
    
    //錯誤
    static void *function(int var1, int var2)
    {
        
    }
    
  • 如果函數返回成功或者錯誤,一般而言,使用 0代表成功,!0代表失敗。

變量和宏

  • 不要使用typedef重定義結構體。這會讓應用程序使用指針訪問這些結構體變得不透明。
  • typedef可以用在簡單數據類型,可以有效的隱藏底層使用的類型或爲其起個別名 (如:os_time_t)。通過添加後綴 _t來標記它們使用了 typedef重定義了。
  • 將函數的所有局部變量定義放在函數體最前面,應位於任何語句或表達式之前。

編譯

  • 代碼編譯必須使用 -Wall參數進行乾淨的編譯。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章