风格"/>
Akagi201的代码风格
Akagi201的代码风格
1. 应用代码和驱动内核代码风格尽量能够统一
2. 工程目录名和文件名为全小写可以加下划线,不用-连接,因为在源码中变量名不能用-连接,所以要用_方便。如:顶层为:chardevice 或 char_device子目录为:app dev 或 client server
3. 顶层makefile写法(待改进,不能make app 这样单独编译)
# Top Makefile
PWD = $(shell pwd)
all:
make -C $(PWD)/app
make -C $(PWD)/dev
clean:
make clean -C $(PWD)/app
make clean -C $(PWD)/dev
.PHONY : all clean
4. 未完成,测试驱动的load脚本 unload脚本。自动读取/proc/devices 自动创建设备节点
5. 头文件宏写法,结合google c++ style和内核以及库文件头文件写法。
从工程顶层目录开始写,最顶层的工程的目录名不写,因为这样每个开头都是一样的没有区分的意义了。宏的开头不以下划线开始,因为内核和库的宏好多用下划线开头的,为了区分,我自己定义的宏不以下划线开头。为了区分头文件的宏与其他变量的宏,结尾处以下划线结尾。后面加个1,可能是为了防止warning把。如
#ifndef APP_GLOBAL_H_
#define APP_GLOBAL_H_ 1
/
#endif // APP_GLOBAL_H_
6. 类型命名:变量名_t 如: pthread_t
7. 变量/结构体变量/命名空间命名: 小写+下划线形式 my_exciting_local_variable
8. 结构体类型命名:结构体变量名_t : typedefstruct snd_card snd_card_t;
9. 全局变量: g_,并且尽可能的声明成static类型,不与其他文件共享的全局变量。
10. 尽量杜绝跨文件访问全局变量。如果的确需要在多个文件内访问同一变量,应该由该变量定义所在文件内提供 GET/PUT函数实现。即共享全局函数而不是共享全局变量。
11. 全局变量必须要有一个初始值,全局变量尽量放在一个专门的函数内初始化。
12. 全局变量的定义和声明技巧:利用宏定义实现
// a.h
#ifdef AAA
int I = 0;
#else
extern int I;
#endif
//a.c 这里可以定义I,也可以在其他文件中定义
…
#include “a.h”
#define AAA
……
//b.c 其他任何文件中声明
…
#include “a.h”
….
13. 所有编译时常量(无论是局部的、全局的还是类中的)和其他变量保持些许区别,k后接大写字母开头的单词:如:const int kDaysInAWeek = 7;
14. 普通函数命名:因为linux库函数很多都是小写单词_小写单词形式如pthread_create()所以为了保持一致,函数命名都统一用小写+下划线形式。
15. 存取函数:存取函数要与存取变量名匹配(小写+下划线形式),此处的小写的函数名意味着可以直接内联使用
…
private:int num_entries_;
…
void set_num_entries(int num_entries){num_entries_ = num_entries;}
16. 枚举/宏命名:全部大写+下划线
17. 词性:除函数名可以适当为动词外,其他命名尽量使用清晰易懂的名词。
18. do{}while(0) 的使用
#define 函数名(大写+下划线)(变量列表) do{(用\换行)}while(0)
#define DBG_PRINT(fmt, args...) \
do \
{ \
DBG_PRINT_LINE(void); \
printk(KERN_ALERT fmt "\n", ## args); \
}while(0)
// 空的时候也用 do{}while(0)
19. 常用global.h头文件
#if defined (__cplusplus) || defined(c_plusplus)
extern "C" {
#endif// 定义NULL指针
#ifndef NULL
#if defined (__cplusplus) || defined(c_plusplus)
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif#ifndef TRUE
#define TRUE 1
#endif#ifndef FALSE
#define FALSE 0
#endif// 自定义数据类型
#ifndef TYPE_UINT8
#define TYPE_UINT8
typedef unsigned char UINT8;
#endif#ifndef TYPE_UINT16
#define TYPE_UINT16
typedef unsigned short UINT16;
#endif#ifndef TYPE_UINT32
#define TYPE_UINT32
typedef unsigned int UINT32;
#endif#ifndef TYPE_INT8
#define TYPE_INT8
typedef char INT8;
#endif#ifndef TYPE_INT16
#define TYPE_INT16
typedef short INT16;
#endif#ifndef TYPE_INT32
#define TYPE_INT32
typedef int INT32;
#endif#ifndef TYPE_FLOAT
#define TYPE_FLOAT
typedef float FLOAT;
#endif#if defined (__cplusplus) || defined(c_plusplus)
}
#endif
20. 注释采用doxygen语法格式,结构体和宏注释用 //>
21. 文件开头 #include 先包含库文件 #include <库名> 再包含自己工程中的文件 #include “文件名”
22. 头文件的名字应该与源文件的名字保持一致。即对应的.h和.c文件文件名保持一致。
23. C语言人为规定为了区分头文件中的函数定义是在对应的.c文件还是在其他的.c文件中,这也许不是不许的,因为无论在哪个文件中定义,聪明的连接程序都能找到。但是,为了方便我们人为地去找头文件中某个函数定义的位置,所以要加extern区分,规则如下:
在.h文件中声明的函数,如果在其对应的.c文件中有定义,那么我们在声明这个函数时,不使用extern修饰符,如果在其他的.c文件中定义的,那么我们要使用extern修饰。
24. 在一个模块文件中, main函数写在最前面,函数声明写在最开始处,实现放在main函数后面。
25. 公司规定的目录结构
include :头文件目录,存放*.h文件。
src :定义文件目录,存放*.c *.cpp文件和本目录内部用的*.h文件。
lib :库文件目录,存放 *.lib和libxxx.a文件。
doc :文档目录,存放相关开发文档。
res :资源目录,存放图片文件、字符文件、字库。
integ_test:放在src目录下的集成测试目录,存放集成测试相关文件。
test:存放示例程序和示例所需要的文件。
26. 用fprintf 代替 printf
27. 头文件中的宏变量都用
#ifndef <宏名>
#define <宏名> <宏值>
#endif
28. 我自己的打印宏:驱动和应用使用一套打印宏,使用与输出打印保持一致。ERR_PRINT待改进,接口未统一,另外,没有加errno 详见我的share/mystyle/debug.h错误捕获函数:代码编译时完全正确,程序可以运行,没有成功调用程序中某些系统调用函数而产生的错误。往往这些系统调用函数通过返回值(1-1 0)来说明是否调用成功,而程序员需要知道详细的错误信息,因此,自建错误捕获函数很有必要。
// 我的打印宏定义
#ifdef DEBUG#ifdef __KERNEL__#define DBG_PRINT_FILE_LINE(void) \do \{ \printk(KERN_EMERG "\n%s:%s():%d:", __FILE__, __func__, __LINE__);\}while (0)#define DBG_PRINT(fmt, args...) \do \{ \DEB_PRINT_FILE_LINE(void); \printk(KERN_EMERG fmt, ##args); \}while (0)#define ERR_PRINT(fmt, args...) \do \{ \printk(KERN_EMERG fmt, ##args); \}while (0)#else#define DBG_PRINT_FILE_LINE(void) \do \{ \fprintf(stderr, "\n%s:%s():%d:", __FILE__, __func__, __LINE__); \}while (0)#define DBG_PRINT(fmt, args...) \do \{ \DBG_PRINT_FILE_LINE(void); fprintf(stderr, fmt, ##args); \}while (0)#define ERR_PRINT(str) \do \{ \DBG_PRINT_FILE_LINE(void); \perror(str); \}while (0)
#else#define DBG_PRINT_FILE_LINE(void) do{}while (0)#define DBG_PRINT(fmt, args...) do{}while (0)#define ERR_PRINT(fmt, args...) do{}while (0)
#endif
更多推荐
Akagi201的代码风格
发布评论