我的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里面的回调函数的参数。