为了在最广泛的环境中获得最佳可读性,请将源代码行的长度保持在 79 个字符或更少。
将 C 函数体开头的左大括号放在第一列非常重要,这样它们会启动一个 defun。一些工具会查找第一列的左大括号来找到 C 函数的开头。这些工具不适用于未按此方式格式化的代码。
避免将左大括号、左圆括号或左方括号放在函数内部的第一列,这样它们就不会启动 defun。如果觉得将 struct
定义视为 defun 很有用,那么启动 struct
主体的左大括号可以放在第一列。
函数定义的函数名从第一列开始也很重要。这有助于人们搜索函数定义,也可能帮助某些工具识别它们。因此,使用标准 C 语法,格式如下
static char * concat (char *s1, char *s2) { … }
或者,如果你想使用传统的 C 语法,像这样格式化定义
static char * concat (s1, s2) /* Name starts in column one here */ char *s1, *s2; { /* Open brace in column one here */ … }
在标准 C 中,如果参数不能很好地放在一行上,则像这样拆分
int lots_of_args (int an_integer, long a_long, short a_short, double a_double, float a_float) …
对于 struct
和 enum
类型,同样将大括号放在第一列,除非整个内容都适合放在一行上
struct foo { int a, b; }
or
struct foo { int a, b; }
本节的其余部分给出了我们关于 C 格式化风格其他方面的建议,这也是 1.2 及更高版本中 indent
程序的默认风格。它对应于以下选项
-nbad -bap -nbc -bbo -bl -bli2 -bls -ncdb -nce -cp1 -cs -di2 -ndj -nfc1 -nfca -hnl -i2 -ip5 -lp -pcs -psl -nsc -nsob
我们不认为这些建议是强制性的,因为如果两个不同的程序有不同的格式化风格,不会给用户带来任何问题。
但是,无论您使用哪种风格,请保持一致,因为在一个程序中混合使用多种风格会显得很丑陋。如果您正在为现有程序贡献更改,请遵循该程序的风格。
对于函数体,我们推荐的风格如下所示
if (x < foo (y, z)) haha = bar[4] + 5; else { while (z) { haha += foo (z, z); z--; } return ++x + bar (); }
我们发现,当在左圆括号之前和逗号之后有空格时,程序更容易阅读。特别是逗号之后。
当您将表达式拆分为多行时,请在运算符之前拆分,而不是在运算符之后拆分。这是正确的方法
if (foo_this_is_long && bar > win (x, y, z) && remaining_condition)
尽量避免在同一缩进级别有两个不同优先级的运算符。例如,不要这样写
mode = (inmode[j] == VOIDmode || GET_MODE_SIZE (outmode[j]) > GET_MODE_SIZE (inmode[j]) ? outmode[j] : inmode[j]);
相反,使用额外的括号,以便缩进显示嵌套
mode = ((inmode[j] == VOIDmode || (GET_MODE_SIZE (outmode[j]) > GET_MODE_SIZE (inmode[j]))) ? outmode[j] : inmode[j]);
插入额外的括号,以便 Emacs 正确缩进代码。例如,以下缩进如果您手动操作,看起来会很好看,
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;
但是 Emacs 会改变它。添加一组括号会产生同样好看的东西,Emacs 会保留它
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);
像这样格式化 do-while 语句
do { a = foo (a); } while (a > 0);
请使用换页符(control-L)将程序在逻辑位置(但不在函数内部)分成多个页面。页面的长度无关紧要,因为它们不必适合打印页面。换页符应该单独出现在单独的行上。