在之前的文章编程规范_这个星球上最好的C编程风格中,介绍了猿届的辟邪剑谱,哦不,是独孤九剑,Google C++ Style Guide。编程规范而已,用不着自宫。为了方便大家,我也专门挑出了C语言相关的部分,并且翻译成了中文,放在我的github上。
本文首发于微信公众号twowinter,转载请注明作者:http://blog.csdn.net/iotisan/
点此进入公众号查看。
程序执行都是由各种各样的语句组成,最常见的有表达式语句和函数调用语句,以及控制语句等。据统计,全世界的程序语句中,条件语句的比例高达67.3%,循环语句也有36.5%。不要问我这个数据怎么得到的,通常开篇都要开个玩笑,好让大家有兴趣把文章看下去。
表达式语句和函数调用很简单,都只有一行,因此只要编程规范上注意下缩进就好。控制语句的花样就多一点,也就是大家最常用的条件语句、循环语句语句。如果不加注意,就会遇到各种样式的ifelse。
我在编程规范_这个星球上最好的C编程风格提到的“几位前辈用连括号前一个空格都不放过的严谨让我受益匪浅”,讲的是关于if语句圆括号与左大括号的空格。很谢谢当时遇到的前辈,这情景现在还印象深刻。
我们团队并没有强制执行这个格式规范,因此就遇到了这样的困扰。于是今天抽空梳理了下,希望大家在平常刻意练习,相互督促,形成一个好的团队编程氛围。
这些都在谷歌C++编程规范的‘格式’章节中,前文编程规范入门篇 空格和tab的区别也是出自这个章节。
提倡不在圆括号中添加空格,关键字else另起一行。 对基本条件语句有两种可以接受的格式,一种在圆括号和条件之间有空格,一种没有。 最常见的是没有空格的格式,那种都可以,还是一致性为主。如果你是在修改一个文件,参考当前已有格式;如果是写新的代码,参考目录下或项目中其他文件的格式,还在徘徊的话,就不要加空格了。
if (condition) { // no spaces inside parentheses
... // 2 space indent.
} else { // The else goes on the same line as the closing brace.
...
}
如果你倾向于在圆括号内部加空格:
if ( condition ) { // spaces inside parentheses - rare
... // 2 space indent.
} else { // The else goes on the same line as the closing brace.
...
}
注意所有情况下if和左圆括号间有个空格,右圆括号和左大括号(如果使用的话)间也要有个空格:
if(condition) // Bad - space missing after IF.
if (condition){ // Bad - space missing before {.
if(condition){ // Doubly bad.
if (condition) { // Good - proper space after IF and before {.
有些条件语句写在同一行以增强可读性,只有当语句简单并且没有使用else子句时使用:
if (x == kFoo) return new Foo();
if (x == kBar) return new Bar();
如果语句有else分支是不允许的:
// Not allowed - IF statement on one line when there is an ELSE clause
if (x) DoThis();
else DoThat();
通常,单行语句不需要使用大括号,如果你喜欢也无可厚非,也有人要求if必须使用大括号:
if (condition)
DoSomething(); // 2 space indent.
if (condition) {
DoSomething(); // 2 space indent.
}
但如果语句中哪一分支使用了大括号的话,其他部分也必须使用:
// Not allowed - curly on IF but not ELSE
if (condition) {
foo;
} else
bar;
// Not allowed - curly on ELSE but not IF
if (condition)
foo;
else {
bar;
}
// Curly braces around both IF and ELSE required because
// one of the clauses used braces.
if (condition) {
foo;
} else {
bar;
}
以团队伙伴新鲜出炉的代码为例。
if(GetCadOrRxStateSwitchflag() ==0)
{
SetCadOrRxStateSwitchflag(1);
}
按照谷歌规范需要做如下修改,我用^号来表示要添加的空格:
if^(GetCadOrRxStateSwitchflag() ==^0)^{
SetCadOrRxStateSwitchflag(1);
}
这里要说明下,除了指针和地址操作符外,其余的操作符的前后都要加空格,因此 ==^0,这边要有个空格。
switch语句可以使用大括号分块;空循环体应使用{}或continue。 switch语句中的case块可以使用大括号也可以不用,取决于你的喜好,使用时要依下文所述。 如果有不满足case枚举条件的值,要总是包含一个default(如果有输入值没有case去处理,编译器将报警)。如果default永不会执行,可以简单的使用assert:
switch (var) {
case 0: { // 2 space indent
... // 4 space indent
break;
}
case 1: {
...
break;
}
default: {
assert(false);
}
}
最近似乎没看到特别的switch,暂且不写。
单句声明的循环体中,括号是可选的。
for (int i = 0; i < kSomeNumber; ++i)
printf("I love you\n");
for (int i = 0; i < kSomeNumber; ++i) {
printf("I take it back\n");
}
空循环,要用括号或者continue,而不能直接用个分号。
while (condition) {
// Repeat test until it returns false.
}
for (int i = 0; i < kSomeNumber; ++i) {} // Good - empty body.
while (condition) continue; // Good - continue indicates no logic.
while (condition); // Bad - looks like part of do/while loop.
for(i=0;i<length;i++)
SPICmd8bit(ptr[i]);
注意对比下,这里有好几个空格要加,实际完成效果如下。
for (i = 0; i < length; i++) {
SPICmd8bit(ptr[i]);
}
虽然谷歌规范说括号是单句声明的循环体,括号是可选的。但是我觉得还是加个括号括起来比较好,万一别人要再加个循环内的语句,忘记加括号就容易发生事故。你加了括号,别人还更省心,可以直接填语句。
好了,就是这点小细节,再见。