发布
2010年7月21日 (上次更新: 2011年8月6日)

更清晰的代码

评分: 3.7/5 (70 票)
*****
我写这篇文章的原因是,很多人似乎不知道(或不在乎)代码的可读性。可读性是可移植性、可重用性和可理解性 (!) 的基础。
如果没有合适的代码,你在这些论坛上寻求帮助时会遭到抱怨,所以仔细阅读;这里有一些清理代码的技巧和窍门。

这是一个指南,我不是说它是完美的。我只是提供一个好的方法,是否使用它由你决定。

本指南不被认为是完整的,但应该可以很好地帮助你入门,欢迎所有建议。

关于括号 始终将括号放在空行上,并将开始和结束括号放在代码中的相同“高度”。两个括号之间的任何内容都应该向右缩进一定数量的空格,这在你的所有代码中都是一致的。(在我的例子中,我使用 4 个空格)这种括号风格称为 Allman 风格。
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>

using std::cout;
using std::endl;

int main()
{
    for(int i = 0; i < 9; i++)
    {
        cout << i << endl;
    }
    return 0;
}

当然,还有其他方法可以做到这一点。一种是 Allman 风格的略微变化:Whitesmith 风格。括号与内部语句位于同一级别。
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>

using std::cout;
using std::endl;

int main()
    {
    for(int i = 0; i < 9; i++)
        {
        cout << i << endl;
        }
    return 0;
    }

当看不清楚文本并不重要,而是要了解不同语句之间的关系(主要是 if/else 关系)时,你也可以使用 1TBS(The One True Brace Style,唯一正确的括号风格)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>

using std::cout;
using std::endl;

int main()
{
    for(int i = 0; i < 9; i++)
    {
        // Allman, up to now, time to go 1TBS for If/Else
        if (i < 5) {
            cout << i << endl;
        } else {
            cout << i*2 << "\t";
        } // And of if/else clause, the last bracket is the only one that takes up it's own line
        // Allman again
    }
    return 0;
}


关于注释 添加注释是为了提高可读性,但也可以使你的注释更具可读性。仅在需要时使用多行注释,并避免在代码行的末尾添加注释。避免缩进注释,使用换行符使内容更清晰。有关更多信息,请参阅关于一致性。

以下注释可能看起来毫无价值,但我只是想明确我上面所说的内容。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>

using std::cout;
using std::endl;

int main()
{
    // Count
    for(int i = 0; i < 9; i++)
    {
        cout << i << endl;
    }

    // Program termination
    return 0;
}


关于一致性(常规) 当不同的替代方案达到相同的结果(以相同的速度和相同的代码行数)时,请确保你坚持使用单一方法。这适用于后置和前置加法和减法(++ / --),以及函数式和 C 风格的转换 int() 和 (int)。
无论你做什么,都要保持一致。

关于函数调用(和定义) 为了可读性,在调用和定义函数的方式上保持一致。不仅有很多方法可以做同样的事情,而且也有很多方法可以编写相同的语句。当你形成自己的编码风格时,尝试坚持一种能够让你保持清晰的方法。一般来说,没有完美的方式来编写事物,但是,有好的方法来为自己编写事物。以下所有提到的方法都是合法的。
1
2
3
power(3, 5)
power( 3,5 )
power(3,5)


关于初始化 一致性也适用于初始化
当可以选择在开始时或稍后初始化时,请使用单一方法。但是,如果你别无选择,只能使用其中一种,那么请使用你需要的那个。此外,在创建指针或引用(或指向指针的指针的指针的引用的 blablabla)时,请使用适当的间距。
以下所有操作都相同(创建一个指向称为 Variable 的整数的指针的引用)。无论哪一种方式能够最好地向你可视化这个结构,都是你的“好方法”。(没有错误的方法,只有“更好”的方法。)
1
2
3
4
int**& Variable;
int **& Variable;
int **&Variable;
int** &Variable;


关于命名
以下是一个指导方针,可以更改(只要它是一致的,当然)。

命名对于函数、类、结构体、联合体、变量、命名空间等都很重要。
如何进行良好的命名?
1. 确保你根据事物的作用(或是什么)来命名它们。
2. 可以选择在它们前面加上一个或两个小写字符,描述命名的实例。(c 代表类,s 代表字符串,i 代表整数,d 代表双精度浮点数等)
3. 每个单词都以大写字符开头,其余字符使用小写。(一个整数可以变成:iNumber)

这些规则的一个例外是循环变量。这些通常用单个小写字符命名。

(所有这些都只是我对一段时间以来的编码习惯的观察。这绝不是一个严格的规则集。它更像是一种编码方式,可以很容易地被任何人阅读。)

关于运算符 运算符可以被视为“数据”的“编辑器”。在这种情况下,最好创建清晰的部分来组织这些“数据”。这种组织取决于你对语句的看法。
1
2
int iNumber = 6+5;
int iReturnValue = 4*iNumber +3;


关于预处理器指令 所有间距和换行规则都适用于此处。但是,对于 #define,请确保使其与普通变量区分开来(使其名称完全大写是一种方法,在其名称之前和之后添加 _ 是另一种方法。你可以随意执行任何操作,只需保持清晰即可。)


最后,你的编程风格是不应该强加给你的。但是,请记住,要收到你代码的反馈,人们需要理解代码。如果你希望人们理解你的代码,请使你的代码清晰易读。