您的位置:首页 > 编程语言 > C语言/C++

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》 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: