我的C编码风格

首先声明一点,我是一个不相信注释的人,所以我的代码不会有很多注释,我代码的注释越多说明我实现的越蹩脚。我的大部分风格与linux kernel code style保持一致,又增加了一点自己的个人习惯。

1. 所有变量函数名全为小写,单词之间用下画线隔开

2. 所有宏全用大写,我把枚举变量的值也视为宏

3. 将Tab键设为8个空格

4. 从不设置编辑器将tab变成空格,在我看来,这简直是强奸民意,比如我自己的编辑器tab是8个空格,但是别人也许更喜欢4个空格呢?

5. 所有关键字与括号之间有空格,双目运算符两边有空格

6. if while for struct 大括号在与if while for struct 在同一行

7. error code从0为成功1到无穷大为错误代码

8. 函数返回值对error code取负,因为可能函数的返回值是正值时是有其他意义的

9. 对于代码参数如果些函数不会修改这个指针指向的内容,那么加上const修饰

10. 不轻易使用typedef,代码是写给懂C语言的人看的,因此我不会去隐藏指针与结构体的存在。

11. 所有经过typedef重定义过的类型,都会在后面加上_t,如aa_t,对于众所周知的u8 u16 u32 s8 s16 s32除外

12. 如果理论上代码的switch绝对不会跑到default,那么我会加上default 并在default中加上类似下面这样一段代码,这样有朝一日脑子抽了加了一个case,那么这个宏就可以起到提醒的作用。

switch(cmd) {
case xxx:
xxx;
break;
default:
assert(!”Unsupport instruct”)
break;
}
13. 所有函数的指针参数在理论上应该不为空的情况下,我会使用assert而不时if (!pointer)这种形式,因为当他为空时本来就是成功的bug,本就应该修复,函数不应该处理这种理论上不存在的错误。

14. 如果一个变量特性是全局的(最简单的一个变量每调某一个函数这个变量会自增1),但是这个变量只在这个函数内被访问,那么在这个函数定义static变量是一个好主义。

15. 同样如果一个全局特性的变量但是只在某一个文件里被访问,那么同样加上static修饰。

16.永远不要使用真正的全局变量,一定有办法可以不用全局变量来优雅的实现。

17. 对于goto,我只想说如果你的goto是只向一个方向走的话,就尽情的用吧!

18. 不要把所有头文件放成include.h里面, 然后在所有头文件包含这个头文件, 试想一下你看到一个includes.h你一眼会看出来这个C文件到底引用了哪些模块了,他与哪些模块耦合了呢?(或许你可以说用source insight, 啊哈或许这是一个好主意,但是一个好的代码不应该只能依靠工具来分析,不是么?),而且当我们包含的头太多时,可以提醒我们这个C文件足够复杂,是否需要分拆了.

19. 如果是纯操作数据,那么类型与数据长度要尽可能的相匹配,而且这种情况要杜绝使用void *,因为读你代码的人不知道你的length是怎么定义的,所以这里延用指针的自增习惯.如:

  int download(unsigned char *buff, unsigned long n);  //n应该是 数据字节数 / sizeof(char)

  int download(unsigned short *buff, unsigned long n);  //n应该是 数据字节数 / sizeof(unsigned short)

  int downlaod(void *buff, unsigned long n);  // 容易使人误解的写法: n ?= 数据字节数 / sizeof(void)

20. 如果有些地方不想让别人操作,而且无关类型的,可以使用void *来躲避类型检查,慎用之,如:http://www.cnblogs.com/findstr/p/3525865.html里面的回调函数的参数。

21. 模块文名最多两个单词如rw_lock.c, 模块结构体采用与文件名相同的命名方式如struct rw_lock, 模块函数名前缀则省略掉下划线如rwlock_get_lock.

发表评论

two + five =