看到別人的編寫的代碼規范非常羨慕,于是也整理總結一份屬于自己的編碼風格,用于規范自己的代碼,增強可讀性,非標準規范。強制自己形成良好的編碼風格,有利于開發大規模程序而不顯得雜亂。 參考STM32固件庫編碼風格和FreeRTOS編碼風格。
一、工程文件組織結構
新建工程文件應包含以下全部或部分文件夾:
·usrSrc:用戶源文件,用來存放.c文件和其他的源文件。main.c應放在這里。
·usrInc:用戶頭文件,用來存放.h文件。
·usrDoc:用戶說明文檔,用來存放用戶在開發過程中書寫的文檔,一般為.txt格式。例如Readme.txt,指令說明等。
·Src:引用庫的源文件。
·Inc:應用庫的頭文件。
·Lib:引用的庫文件。一個工程一定要包含一個main.c文件,只用來存放main函數。其余函數的定義應在相應的.c文件中,聲明在相應的.h文件中。
源文件
·文件頭,文件的簡介
/*************************************************************************
* Copyright (c) 2017, Jimbo Zhang
* All rights reserved.
*
* File name : USB_Ctrl.c
* Brief : USB API source code.
* Introduce the main function or content of this document briefly.
* Revision : 1.01
* Author : Jimbo Zhang
* Date : 2017.03.10
* Update : Introduce the difference from previous version.*************************************************************************/
·必要的注釋和說明源文件應該只包含它自己的頭文件,其他的頭文件在他自己的頭文件中包含。源文件中只聲明局部函數,全局函數在頭文件中聲明。全局變量在相應的源文件中定義,在頭文件中用extern聲明。類型定義在頭文件中定義。
/* Includes -----------------------------------------------------------*/
/*only include it's own header file, theothers header fileincluded byUSB_Ctrl.h*/#include "USB_Ctrl.h"
/* Declaration --------------------------------------------------------*/
/*here are thelocalfunction declare, globalfuction declare inheader file.*/
void delay( uint32_t n);
/* Global variable ----------------------------------------------------*/
·函數頭
/******************************************************* Brief : Delay n ms* Parameter : * n: the number of delay microsecond.* Return : None.*******************************************************/
void delay( uint32_t n)
{for( i=0; i<110; i++) ???????;
}
頭文件
·文件頭,文件的簡介
/*************************************************************************
- Copyright (c) 2017, Jimbo Zhang
- All rights reserved.
-
- File name : USB_Ctrl.h
- Brief : The header file of USB_Ctrl.c.
- Revision : 1.01
- Author : Jimbo Zhang
- Date : 2017.03.10
- Update : Introduce the difference from previous version.*************************************************************************/
·必要的注釋和聲明
/* Includes -----------------------------------------------------------*/
/* Define -------------------------------------------------------------*/
/* Typedef ------------------------------------------------------------*/typedefunsignedintapiStatus; //api return code
/* Enume --------------------------------------------------------------*/
/* Extern -------------------------------------------------------------*/
/* Declaration --------------------------------------------------------*/
命名規則
參考FreeRTOS命名規則,MISRA C規范。- 定義變量時盡量使用uint8_t 、uint16_t 、uint32_t等。頭文件為stdint.h。
typedefsignedcharint8_t;typedefshortint16_t;typedefintint32_t;typedeflonglongint64_t;typedefunsignedcharuint8_t;typedefunsignedshortuint16_t;typedefunsignedintuint32_t;typedefunsignedlonglonguint64_t;
·uint32_t類型的變量使用前綴ul,這里’u’表示’unsigned’,’l’表示’long’
·uint16_t類型的變量使用前綴us,這里’u’表示’unsigned’,’s’表示’short’
·uint8_t類型的變量使用前綴uc,這里’u’表示’unsigned’,’c’表示’char’
·枚舉類型變量使用前綴e
·指針類型變量在類型基礎上附加前綴p,比如指向uint16_t的指針變量前綴為pus
·與MISRA指南一致,char類型變量僅被允許保存ASCII字符,前綴為c
·與MISRA指南一致,char *類型變量僅允許指向ASCII字符串,前綴為pc
·宏定義全部使用大寫,兩個單詞之間用下劃線隔開。
·具有文件作用域的對象盡量聲名為static的。
·全局變量加前綴’g_’。整個工程都可以用的變量,不局限于文件作用域。
代碼風格
·縮進:縮進使用制表符,一個制表符等于4個空格。
·注釋:注釋單行不超過80列,特殊情況除外。
·布局:源代碼應被設計成盡可能的易于查看和閱讀。
下面的代碼片中,第一部分展示文件布局,第二部分展示C代碼設計格式。
/* #defines, 在合理的位置添加括號. */#define A_DEFINITION ( 1 )
/*
* 隨后是Static (文件內部的)函數原型,
* 如果注釋有多行,參照本條注釋風格---每一行都以’*’起始.
*/staticvoidprvAFunction( uint32_t ulParameter );
/* 文件作用域變量(本文件內部使用),要在函數體定義之前. */staticBaseType_t xMyVariable.
/* 每一個函數的結束都有一行破折號,破折號與下面的第一個函數之間留一行空白。*/
/*-----------------------------------------------------------*/
voidvAFunction( void)
{
/* 函數體在此定義,注意要用大括號括住 */
} /*-----------------------------------------------------------*/
staticUBaseType_t prvNextFunction( void)
{
/* 函數體在此定義. */
} /*-----------------------------------------------------------*/
/*
* 函數名字總是占一行,包括返回類型。 左括號之前沒有空格左括號之后有一個空格,
* 每個參數后面有一個空格,參數的命名應該具有一定的描述性.
*/voidvAnExampleFunction( longlParameter1, unsignedshortusParameter2 )
{ /* 變量聲明沒有縮進. */
uint8_t ucByte;
/* 代碼要對齊. 大括號占獨自一行. */
for( ucByte = 0U; ucByte < fileBUFFER_LENGTH; ucByte++ ) ???
{
/* 這里再次縮進. */
}
}
/*
* for、while、do、if結構具有相似的模式。這些關鍵字和左括號之間沒有空格。
* 左括號之后有一個空格,右括號前面也有一個空格,每個分號后面有一個空格。
* 每個運算符的前后各一個空格。使用圓括號明確運算符的優先級。不允許有0
* 以外的數字(魔鬼數)出現,必要時將這些數字換成能表示出數字含義的常量或
* 宏定義。
*/for( ucByte = 0U; ucByte < fileBUFFER_LENGTH; ucByte++ ) ???
{
}
while( ucByte < fileBUFFER_LENGTH ) ???
{
}
/*
* 由于運算符優先級的復雜性,我們不能相信自己對運算符優先級時刻保持警惕
* 并能正確的使用,因此對于多個表達式運算時,使用括號明確優先級順序
*/if( ( ucByte < fileBUFFER_LENGTH ) && ( ucByte != 0U?) ) ???
{
ulResult = ( ( ulValue1 + ulValue2 ) - ulValue3 ) * ulValue4;
}
/* 條件表達式也要像其它代碼那樣對齊。 */#if( configUSE_TRACE_FACILITY == 1 )
{
/* 向TCB增加一個用于跟蹤的計數器. */
pxNewTCB->uxTCBNumber = uxTaskNumber;
} #endif
/*方括號前后各留一個空格*/
ucBuffer[ 0] = 0U;
ucBuffer[ fileBUFFER_LENGTH - 1U] = 0U;
編程思想
·將特定功能的代碼封裝成函數。
C語言編程規則
參考MISRA
·Rule1:不得使用三元操作符(? : )。
·Rule2:不得殘留被注釋掉的廢代碼。
·Rule3:所有標識符不超過31字符。
·
Rule4:不同名空間中的變量名不得相同。例如:typedef struct MyStruct {... } MyStruct; (違規)
·
struct Person {
char* name;
...
};
char name[32]; (違規)
·Rule5: 不得使用char, int, float, double, long等基本類型,應該用stdint.h中定義的類型顯示表示類型的大小,如uint16_t、int32_t等。
·Rule6:禁止使用八進制數。(因為086U這樣的常數很容易引起誤解)。
·Rule7:不得定義與外部作用域中某個標識符同名的對象,以避免遮蓋外部作用域中的標識符。
·Rule8:具有文件作用域的對象盡量聲名為static的。
·Rule9:自動對象(棧對象)使用前必須賦初值。
·
Rule10:操作符&&和||的右側表達式不得具有副作用(side-effect)。也就是說,象 if (x == 20 && ++y == 19)這樣的表達式被禁止。
·
·
Rule11:不得對有符號數施加位操作,例如 1 << 4 將被禁止,必須寫 1UL << 4。
·
·Rule12:不得對有副作用的表達式施加sizeof操作符。
·Rule13: 除了循環控制語句,不得使用逗號表達式。
·Rule14:不得顯式判斷浮點數的相等性和不等性。
·Rule15:不得遺留“永遠不會用到”的代碼。
·Rule16:除了switch語句,不得使用標號(label)。
·Rule17:不得使用goto。
·Rule18:不得使用continue。
·Rule19:除了switch語句,不得使用break
·Rule20:if, else if, else, while, do..while, for語句塊必須使用{}括起。
·Rule21:循環計數器的值不得在循環體內修改。
·Rule22:禁止任何直接和間接的遞歸函數調用。
·Rule23:不應該使用#undef。
·Rule24:不得將宏作為參數傳給宏函數。
·Rule25:在一個宏定義中,#或##符號只能出現一次。
·Rule26:禁止指針運算(代之以數組下標運算)。
·Rule27:禁止超過兩級的指針。
·Rule28:禁止使用指向函數的非常量指針。
·Rule29:禁止使用setjmp, longjmp。
·Rule30:禁止使用atoi, atof, atol。(這個我很贊成,建議使用strtol, strtod等函數)
·Rule31:禁止使用abort, exit, getenv。
-
嵌入式
+關注
關注
5088文章
19158瀏覽量
306483 -
C語言
+關注
關注
180文章
7614瀏覽量
137257 -
編碼
+關注
關注
6文章
952瀏覽量
54888
原文標題:嵌入式er日常!強制自己形成良好的編碼風格
文章出處:【微信號:gh_c472c2199c88,微信公眾號:嵌入式微處理器】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論