C/C++代码风格摘录
2011-08-06 14:24
253 查看
Naming:
库命名:库的前缀长度大于两个字符,所有的变量及函数都以该前缀开始。
外部符号以'_'开头。
命名内容:
不要顾虑名字长度,如
intnum_errors;
intnum_completed_connections;
变量和类型用名词:num_errors。
函数用动作或者动词+名词:OpenFile()。
命名缩写:
尽可能不用缩写,如果要用也用知名的编写:
index-> idx
count-> cnt
Filedescriptor -> fd
Number-> num
Error-> err
文件名:
文件名尽可能在14个字母以下,否则在一些老的系统(SystemV)中可能会出现问题。
小写+'_',如my_class.cc,other_class.c,C++用cc结尾。
类型:
包括class, struct, typedef enum。每个单词首字母大写,如MyClass。
如果class中
1. 全是纯虚函数。
2. 没有非静态成员变量。
3. 无需constructor,有的话为protected。
4. 如果是子类,则父类满足以上这几条。
则类以Interface为后缀。
变量:
一般变量小写+'_',如data_name。
类成员变量在末尾加'_',如data_name_。
全局变量前加g_,如g_grid。
编译期常数用k+混合大小写,发kFileNum。
常量:
以k开头,单词首字母大写,如kMaxNum。
函数:
单词首字母大写,如AddTableEntry()。
get和set函数应和相应变量一致,如name_的set函数为set_name,get函数为name,get可省略。
另外,非常短的内联函数名可以全小写。
Namespace:
基于项目名的全小写+'_'。
Macro:
如果非要用的话,大写+'_',如M_PI, MAX(x, y)。
Style
Macro:Conditionalcompilation (GNU)
if (HAS_FOO)
…
else
…
Insteadof
#ifdefHAS_FOO
…
#else
…
#endif
error:
每一个system call都要用perror返回错误信息,malloc和realloc检查是否返回NULL。
用getopt_long解码参数。
Signal:
信号机制用POSIX系统的。
Tempfile:
要产生临时文件,检查环境变量TMPDIR,如果定义,用该定义代替'/tmp'。为了避免产生所有用户都能写的临时文件所产生的安全问题,用
fd = open (filename,O_WRONLY | O_CREAT |O_EXCL, 0600);
或mkstemps。
输出的消息:
source-file-name:lineno:message
加列号
source-file-name:lineno:column:message
source-file-name:lineno.column:message
跨行列:
source-file-name:lineno-1.column-1-lineno-2.column-2:message
source-file-name:lineno-1.column-1-column-2:message
source-file-name:lineno-1-lineno-2:message
跨文件:
file-1:lineno-1.column-1-file-2:lineno-2.column-2:message
非交互式程序指明源文件:
program:source-file-name:lineno:message
非交互式程序不指明源文件:
program: message
指明源文件加列号:
program:source-file-name:lineno:column:message
其中message如果跟在其它信息后,小写开头,不加句号。类似usage的输出大写开头,但不加句号。
参数:
用getopt_long处理程序参数。
输入文件不用加额外参数,输出文件前加'-o'或'--output'
提供'--version'和'--help'参数,'--version'例:
GNUhello 2.3
Copyright(C) 2007 Free Software Foundation,Inc.
LicenseGPLv3+: GNU GPL version 3 or later<http://gnu.org/licenses/gpl.html>
Thisis free software: you are free to changeand redistribute it.
Thereis NO WARRANTY, to the extent permittedby law.
'--help'末尾信息:
Reportbugs to: mailing-address
pkghome page: <http://www.gnu.org/software/pkg/>
Generalhelp using GNU software: <http://www.gnu.org/gethelp/>
缩进:
关键字旁空一格,括号不换行,以下右边是GNU建议的格式,但个人觉得分得太开了,一页放的内容就相对少了,左边是个人建议用的格式,除非你所在的地方按行发工资。
do { a = foo (a); } while (a > 0); | do { a = foo (a); } while (a > 0); |
if (x < foo (y, z)) { haha = bar[4] + 5; } else { while (z) { haha += foo (z, z); z--; } return ++x + bar (); } | if (x < foo (y, z)) haha = bar[4] + 5; else { while (z) { haha += foo (z, z); z--; } return ++x + bar (); } |
多加一些看似多余的括号,一方面使语义更清楚,另一方面使一些编辑器不会产生一些看似恶心的自动缩进。
v= (rup->ru_utime.tv_sec*1000 +rup->ru_utime.tv_usec/1000
+rup->ru_stime.tv_sec*1000 +rup->ru_stime.tv_usec/1000);
把函数名放在行首,传说对某些文本处理软件有好处。Linux kernel源代码里貌似很多是这种风格,但又不全是。
static char *
concat (char *s1, char *s2)
{
…
}
条件语句太长要换行时。
If(foo_this_is_long && bar >win(x, y, z)
&&remaining_condition)
注释:
每个函数,文件都尽可能写注释,尽可能用英语写。
在每句注释后加两个空格,据说这样对Emacs的语句命令有好处。
每句注释都要完整,并且首字母大写。
#ifdeffoo
...
#else/* not foo */
...
#endif/* not foo */
#ifdeffoo
...
#endif/* foo */
#ifndeffoo
...
#else/* foo */
...
#endif/* foo */
#ifndeffoo
...
#endif/* not foo */
构造声明:
extern函数声明在文件开始处,即其它函数定义前,或者放在头文件中。
定义每个变量都要加类型,如:
int foo;
int bar;
定义声明和变量分开,如:
typedefdouble new_type;
new_typedata;
不要在if语句里赋值,但在while里可以:
Good foo = (char *) malloc (sizeof *foo); if (foo == 0) fatal ("virtual memory exhausted"); | Bad if ((foo = (char *) malloc (sizeof *foo)) == 0) fatal ("virtual memory exhausted"); |
移植性(Portability):
最简单的方法是使用autoconf。
"feature_test_macro" _GNU_SOURCE能帮助找出那些与GNU库扩展函数重名的函数。
standard C库函数的移植问题:
1. sprintf的返回值不是在所有的系统中都返回写入的字符数。
2. vfprintf在一些系统中并不一定可用。
3. main的返回值为int,结束时用return+返回值或exit()。
4. 有些系统用'string.h' ,有些则是'strings.h',用autoconf决定用哪个。
5. string函数中建议用的函数有以下几个:strcpy strncpy strcat strncat strlen strcmp strncmp strchr strrchr
如果所在系统没有某些系统函数,用marcro执行检查:
#ifndef HAVE_STRCHR
#define strchr index
#endif
#ifndef HAVE_STRRCHR
#define strrchrrindex
#endif
char *strchr ();
char *strrchr ();
声明:
enum {MAX_NESTED_LINKS = 5 };
Compile:
如想让GCC以StandardC标准工作,编译加'--pedantic'。
如果让GCC以POSIX标准工作,添加环境变量'POSIXLY_CORRECT'
Class:
Miscellaneous:constructor中仅初始化成员变量,其它代码放到单独的函数init()。
应该定义默认的constructor。
如果constructor只带一个参数,加上explicit关键字防止隐式conversion。
Copy constructor和assignment operator只在有必要的时候才定义,否则把它们设为private。
destructor定义为虚函数,否则析构时没法调用正确的子类destructor。
不要在constructor和destructor中调用虚函数,那个时候类是“不完整”,虚函数机制只有在类被构造完成后才能正常。
Declaration Order:
先public,后protected,最后private,如果是某段为空,则无需加该关键字;先method,后variables。
在同一section中,顺序为:
typedef and enum
Constants (static constvariable)
Constructor
Destructor
Methods, including staticones
Data member
Friend成员应在private段中。实现文件中的定义顺序尽可能和声明顺序一样。
最后,代码风格的最高原则是服从已有项目的风格,无论已有的风格是多完美还是多糟糕。
以上都是看相关书时随手摘录下来,记不得具体来源,下面是可能参考到的文献:
《Google C++ Style Guide》
《GNU Coding Standards》
《C Traps and Pitfall》
《The Practice of Programming》
《C++命名规则》
《Effective C++ ThirdEdition 55 Specific Ways to Improve Your Programs and Designs》
《Inside the C++Object Model》
相关文章推荐
- Emacs 设置C++代码风格
- Google放出C++代码风格规范
- C++代码风格与规范
- [C++] 代码C风格缩进
- 【cocos2d-x从c++到js】20:脚本语言风格的JS代码 推荐
- C++基础学习之11 - 初谈代码风格
- 《C++ primer》学习笔记之十三:一段很好看的c++代码,由此得出的编程风格
- C++良好代码风格之我见 - 兼谈boost的工程实用价值
- C++代码风格检查
- [C++] 编程实践之1: Google的C++代码风格1:头文件
- [C++] 编程实践之1: Google的C++代码风格3:类
- C++良好代码风格之我见 - 兼谈boost的工程实用价值
- 要养成的c++代码编写风格:
- C++代码风格
- 向google学习良好的C++代码风格-(1)概述
- C++代码风格04
- C++代码风格与规范
- C++代码风格指南总结
- 向google学习良好的C++代码风格-(2)头文件
- C++代码风格的思考