C語言編程規范(個人整理)
- 前言
- 1、基本命名規則
- 2、排版規則
- 3、編程規則
- 4、使用宏定義列印Debug資訊
前言
??寫這篇博客主要是希望自己能夠按照這篇編程規范進行編程,
1、基本命名規則
規則:
- 檔案名,函式,結構體,聯合體,列舉 --> 大駝峰
- 變數,函式引數,宏引數,結構體欄位,聯合體成員 --> 小駝峰
- 宏,常量,列舉值,goto標簽 --> 全大寫,下劃線分割
- 全域變數應增加 'g_'前綴,區域靜態變數不加前綴
- 指標變數使用’p’前綴
- bool型別變數使用’b’前綴
建議:
- 作用域越大,命名應越精確,包括函式和變數
- 動作類函式,可以使用動賓結構,如:AddUser(),DeleteUser()
- 判斷型函式,可以使用形容詞或加is,如:DataReady(),IsWorking()
- 資料型函式,如:GetTotalCount()
- 區域變數命名應該簡短,且能表達相關含義
- 通過 typedef 對結構體,聯合體,列舉起別名時,盡量使用匿名型別,如:
typedef struct{
char userName;
int userId;
}User;
- 需要指標自嵌套,可以增加’tag’前綴,如:
typedef struct tagTaskList{
int userData;
struct tagTaskList *pPrev;
struct tagTaskList *pNext;
}TaskList;
2、排版規則
規則:
- 回圈陳述句,條件陳述句必須要大括號,即便是空陳述句或只有一條陳述句
- 禁止 if / else / else if 寫同一行
- if 左括號和 if 同一行,右括號和 else 以及 else 左括號一行,for 回圈同理
- 多個變數定義和賦值陳述句不能寫在同一行
- 代碼縮進要求是4個空格
- 函式中的不同代碼塊之間要空一行,注釋寫在代碼塊前,如:
int GetTotalCount(int *arr, int len){
int count = 0;
//notes:
for(int i = 0; i < len; i++){
if(arr[i] > =5){
count++;
}
}
return count;
}
3、編程規則
規則:
- 每一個 .c 檔案都需要對應 .h 檔案,用于放置對外提供的函式宣告、宏定義、型別定義等,不對外使用的函式可以用 static 限制
- 包含頭檔案時,應先包含穩定的頭檔案,順序:標準C函式庫,第三方庫,自己寫的頭檔案
#include <stdio.h> //標準c庫
#include <string.h> //標準c庫
#include <srt/srt.h> //srt協議第三方庫
#include "Test.h" //自己寫的
- 使用 #ifndef 防止頭檔案重復包含(或者#pragma once),如Test.h
#ifndef TEST_H_
#define TEST_H_
...
...
#endif /* TEST_H_ */
- 盡量不用 extern 呼叫外部變數和函式,應將這些變數和函式放在 .h 檔案中,以供外部使用
- 呼叫函式要判斷回傳值,尤其這個回傳值將被后續函式呼叫時,呼叫前要先檢查回傳值是否合理
- 如果不關心回傳值,應將函式宣告為void型別
- 函式指標的指標引數,應確定是否使用const修飾
- 多個 .c 檔案要呼叫同一個行內函式,那么這個行內函式應該在 .h 中定義(否則無法行內,因為行內函式是在編譯階段展開的), 且行內函式不超過10行
- 宏函式并沒有型別檢查,可以考慮用行內函式代替
- 全域變數要少用,其它 .c 檔案需要用到其他檔案的全域變數時,盡量用函式介面提供全域變數
- #ifdef __cplusplus 可以用來避免C編譯器編譯 extern C 而出錯
#ifdef __cplusplus
extern "C"{
#endif
...
...
#ifdef __cplusplus
}
#endif
4、使用宏定義列印Debug資訊
- 使用斷言函式,函式原型 void assert( int expression ),實際上是一個宏定義函式, 如果運算式為真,繼續執行;如果運算式為假,列印錯誤資訊,呼叫 abort() 函式終止程式運行,此外,在 assert.h 頭檔案前使用#define NDEBUG 可以關閉斷言函式,
#include <stdio.h>
//#define NDEBUG //可以關閉assert斷言函式
#include <assert.h> //斷言函式頭檔案
int main(){
int ret = GetCount();
assert(ret >= 0); //用于判斷函式回傳值,ret < 0 程式終止
return;
}
- 使用自定義的宏函式,如下:
#define PRINT_LOG 1
#define PRINT_ALOG 0
#if PRINT_LOG
#if PRINT_ALOG
#define ALOG(fmt, ...) printf("%s:%s:%d "fmt, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__);
#define LOG(fmt, ...) ALOG(fmt, __VA_ARGS__) //advance print 攜帶檔案名、函式名、行號資訊
#else
#define OLOG(fmt, ...) printf(fmt, __VA_ARGS__)
#define LOG(fmt, ...) OLOG(fmt, __VA_ARGS__) //ordinary print
#endif
#else
#define LOG(fmt, ...)
#endif
//用于列印字串 如:LOGSTR("Init successed\n");
#define LOG_STR 1
#if LOG_STR
#define LOGSTR(...) printf(__VA_ARGS__)
#else
#define LOGSTR(...)
#endif
/*
* 使用方式:
* LOG用于列印帶格式輸出的字串,
* 在宏定義PRINT_ALOG為0時,列印ind和count資訊;
* 在宏定義PRINT_ALOG為1時,能夠額外列印檔案名、函式名、行號資訊,
* LOG("ind:%d\t count:%d\n", ind, count);
* LOG_STR用于列印不帶格式輸出的字串
* LOG_STR("Init successed\n");
*/
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/282882.html
標籤:其他
上一篇:Vue回應式原理的簡單模型
