第三章:大括号和空格的放置
C语言风格中另外一个常见问题是大括号的放置。和缩进大小不同,选择或弃用某种放置策略并没有多少技术上的原因,不过首选的方式,就像Kernighan和Ritchie展示给我们的,是把起始大括号放在行尾,而把结束大括号放在行首,所以:
if (x is
true) {
we do y
}
这适用于所有的非函数语句块(if、switch、for、while、do)。比如:
switch (action) {
case
KOBJ_ADD:
return "add";
case
KOBJ_REMOVE:
return "remove";
case
KOBJ_CHANGE:
return "change";
default:
return NULL;
}
不过,有一种特殊情况,命名函数:它们的起始大括号放置于下一行的开头,这样:
int
function(int x)
{
body of function
}
全世界的异端可能会抱怨这个不一致性,呃…确实是不一致的,不过所有思维健全的人都知道(a)K&R是 正确的, 并且(b)K&R是正确的。另外,不管怎样函数都是特殊的(在C语言中,函数是不能嵌套的)。
注意结束大括号独自占据一行,除非它后面跟着同一个语句的剩余部分,比如说do语句中的“while”或者if语句中的“else”,像这样:
do {
body of do-loop
} while
(condition);
和
if (x ==
y) {
..
} else
if (x > y) {
...
} else {
....
}
理由:K&R。也请注意这种大括号的放置方式还能使空(或者差不多空的)行的数量最小化,同时不失可读性。因此,由于你的屏幕上的新行的供应不是可回收的资源(想想25行的终端屏幕),你将会有更多的空行来放置注释。
仅有一个单独的语句时,不用加不必要的大括号。
if (condition)
action();
这点不适用于本身为某个条件语句的一个分支的单独语句。这时应该两个分支里都使用大括号。
if (condition) {
do_this();
do_that();
} else {
otherwise();
}
3.1:空格
Linux内核的空格使用方格(主要)取决于它是用于函数还是关键字。(大多数)关键字后要加一个空格。值得注意的例外是sizeof、typeof、alignof和__attribute__,这些关键字在一定程度上看起来更像函数(它们在Linux里也常常伴随小括号使用,尽管在C语言里这样的小括号不是必需的,就像“struct fileinfo info”声明过后的“sizeof info”)
所以在这些关键字之后放一个空格:
if,
switch, case, for, do, while
但是不在sizeof、typeof、alignof或者__attribute__这些关键字之后放空格。例如,
s =
sizeof(struct file);
不要在小括号里的表达式两侧加空格。这是一个反例:
s =
sizeof( struct file );
当声明指针类型或者返回指针类型的函数时,“*”的首选使用方式是使之靠近变量名或者函数名,而不是靠近类型名。例子:
char
*linux_banner;
unsigned
long long memparse(char *ptr, char **retptr);
char
*match_strdup(substring_t *s);
在大多数二元和三元操作符两侧使用一个空格,例如下面所有这些操作符:
= + - <
> * /
% | &
^ <= >=
== != ? :
但是一元操作符后不要加空格:
& * +
- ~ !
sizeof typeof alignof
__attribute__ defined
后缀自增和自减一元操作符前不加空格:
++ --
前缀自增和自减一元操作符后不加空格:
++ --
“.”和“->”结构体成员操作符前后不加空格。
不要在行尾留空白。有些可以自动缩进的编辑器会在新行的行首加入适量的空白,然后你就可以直接在那一行输入代码。不过假如你最后没有在那一行输入代码,有些编辑器就不会移除已经加入的空白,就像你故意留下一个只有空白的行。包含行尾空白的行就这样产生了。
当Git发现补丁包含了行尾空白的时候会警告你,并且可以应你的要求去掉行尾空白;不过如果你是正在打一系列补丁,这样做会导致后面的补丁失败,因为你改变了补丁的上下文。
|