編碼規範------華爲篇

編碼規範很重要,其實他直接影響到了代碼迭代更新的效率和出問題的概率。以下爲本人對網上廣爲流傳的華爲編碼規範的個人總結。(ps:其中有幾個原則實在是精闢的不能再精闢了,當然也有一些存在疑惑,還希望各位大佬不吝賜教)

1.不要使用難懂的技巧性很高的語句,除非很有必要時

高技巧語句不等於高效率的程序,實際上程序的效率關鍵在於算法。這可能是很多初學者最容易犯得錯誤。

2.去掉沒必要的公共變量

公共變量是增大模塊間耦合的原因之一。全局變量雖然好用,但是宜少不宜多這樣能保證數據的安全性。

3.當向公共變量傳遞數據時,最好做數據合法性檢查。

有必要最好做一下,因爲萬一出了問題是不好檢測出來的。

4.構造僅有一個模塊或函數可以修改、創建,而其餘有關模塊或函數只訪問的公共變量,
防止多個不同模塊或函數都可以修改、創建同一公共變量的現象

還是前面講到的數據安全性問題,可以通過靜態函數實現,且整個系統都要保持一致

5.仔細設計結構中元素的佈局與排列順序, 使結構容易理解、 節省佔用空間, 並減少引起
誤用現象

示例:如下結構中的位域排列,將佔較大空間,可讀性也稍差。
typedef struct EXAMPLE_STRU
{
unsigned int valid: 1;
PERSON person;
unsigned int set_flg: 1;
} EXAMPLE;


若改成如下形式,不僅可節省 1 字節空間,可讀性也變好了。
typedef struct EXAMPLE_STRU
{
unsigned int valid: 1;
unsigned int set_flg: 1;
PERSON person ;
} EXAMPLE;

6.儘量減少沒有必要的數據類型默認轉換與強制轉換。

7.對所調用函數的錯誤返回碼要仔細、全面地處理

Linux系統裏好像是不允許有空函數的

8.防止將函數的參數作爲工作變量

將函數的參數作爲工作變量, 有可能錯誤地改變參數內容, 所以很危險。 對必須改
變的參數,最好先用局部變量代之,最後再將該局部變量的內容賦給該參數。

示例:下函數的實現不太好。
void sum_data( unsigned int num, int *data, int *sum )
{
unsigned int count;
*sum = 0;
for (count = 0; count < num; count++)
{
*sum += data[count]; // sum 成了工作變量,不太好。
}
}
若改爲如下,則更好些。
void sum_data( unsigned int num, int *data, int *sum )
{
unsigned int count ;
int sum_temp;
sum_temp = 0;
for (count = 0; count < num; count ++)
{
sum_temp += data[count];
}
*sum = sum_temp;
}

9.一個函數僅完成一件功能。

10.避免設計多參數函數,不使用的參數從接口中去掉。

目的減少函數間接口的複雜度,參數多的話可以通過結構體實現

11.非調度函數應減少或防止控制參數,儘量只使用數據參數

避免函數功能不明確,給調試帶來麻煩


示例:如下函數構造不太合理。
int add_sub( int a, int b, unsigned char add_sub_flg )
{
    if (add_sub_flg == INTEGER_ADD)
    {
        return (a + b);
    }
    else
    {
        return (a - b);
    }
}

不如分爲如下兩個函數清晰。
int add( int a, int b )
{
    return (a + b);
}
int sub( int a, int b )
{
    return (a - b);
}

12.檢查函數所有參數輸入的有效性

功能不明確較小的函數,特別是僅有一個上級函數調用它時, 應考慮把它合併到上級
函數中, 而不必單獨存在

13.設計高扇入、 合理扇出(小於7) 的函數。

函數較合理的扇出(調度函數除外) 通常是 3-5.較良好的軟件結構通常是頂層函數的扇出較高, 中層函數的扇出較少, 而底層函數則扇入到公共模塊中。還是強調函數的高複用性和可讀性

14.避免使用BOOL參數

TURE/FALSE 的含義是非常模糊的,這點確實有點驚訝,對於那些內存要求不是很苛刻的能不用就不用吧

15.對於提供了返回值的函數, 在引用時最好使用其返回值。

16.當一個變量名較長且有較多引用時(一般是結構的成員), 可以用一個
意義相當的宏代替

也可以定義一個局部變量,在用之前對局部變量賦值

17.在同一項目組或產品組內, 調測打印出的信息串的格式要有統一的形式。 信息串中至少
要有所在模塊名(或源文件名) 及行號

行號和文件名可以用宏__LINE__和__FILE__實現

18.使用斷言來發現軟件問題, 提高代碼可測性。

斷言可以對在系統中隱藏很深, 用其它手段極難發現的問題進行定位

示例:下面是 C 語言中的一個斷言,用宏來設計的。(其中 NULL 爲 0L)

#ifdef _EXAM_ASSERT_TEST_ // 若使用斷言測試
void exam_assert( char * file_name, unsigned int line_no )
{
    printf( "\n[EXAM]Assert failed: %s, line %u\n",file_name, line_no );
    abort( );
}

#define EXAM_ASSERT( condition )
if (condition) // 若條件成立,則無動作
    NULL;
else // 否則報告
    exam_assert( __FILE__, __LINE__ )
#else // 若不使用斷言測試
#define EXAM_ASSERT(condition) NULL
#endif /* end of ASSERT */

19.在編寫代碼之前, 應預先設計好程序調試與測試的方法和手段, 並設計好各種調測開關
及相應測試代碼如打印函數等

20.在保證軟件系統的正確性、 穩定性、可讀性及可測性的前提下, 提高代碼效率。

21.避免循環體內含判斷語句, 應將循環語句置於判斷語句的代碼塊之中

筆者確實踩過這樣的坑,並且真的很難發現是什麼問題。另外循環嵌套儘量不要超過三層且不要太複雜。

22.儘量用乘法或其它方法代替除法,特別是浮點運算中的除法。

浮點運算除法要佔用較多 CPU 資源。應爲一般的cpu只有硬件乘法器

23.過程/函數中申請的(爲打開文件而使用的)文件句柄,在過程/函數退出之前要關閉。

分配的內存不釋放以及文件句柄不關閉, 是較常見的錯誤, 而且稍不注意就有可能發生。這類錯誤往往會引起很嚴重後果,且難以定位

24.有可能的話, if語句儘量加上else分支, 對沒有else分支的語句要小心對待; switch
語句必須有default分支。

25.時刻注意表達式是否會上溢、 下溢。


示例:如下程序將造成變量下溢。
unsigned char size ;
while (size-- >= 0) // 將出現下溢
{
... // program code
}

26.打開編譯器的所有警告開關對程序進行編譯

27.某些語句經編譯後產生警告,但如果你認爲它是正確的,那麼應通過某種手段去掉告
警信息

示例:
#pragma warn -rvl // 關閉告警
int examples_fun( void )
{
// 程序,但無 return 語句。
}
#pragma warn +rvl // 打開告警

28.使用代碼檢查工具(如C語言用PC-Lint)對源程序檢查。使用軟件工具(如 LogiSCOPE)進行代碼審查

用過其中一個,效果不理想可能是不會用吧

29.不應通過“試” 來解決問題,應尋找問題的根本原因

最精闢的原則之一,可很多人就是通過“試”

30.對自動消失的錯誤進行分析,搞清楚錯誤是如何消失的

最精闢的原則之一,對於提高能力有很大幫助

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章