原文链接
注释是程序员可读的注释,直接插入到程序的源代码中。注释将被编译器忽略,仅供程序员使用。在C ++中,有两种不同的注释样式,它们都具有相同的目的:帮助程序员以某种方式记录代码。
单行注释(Single-line comments)
C ++单行注释以符号“//”开始,该符号//告诉编译器忽略//符号以及到行尾的所有内容。例如:
std::cout << "Hello world!"; // Everything from here to the end of the line is ignored
通常,单行注释用于对单行代码进行快速注释。
std::cout << "Hello world!\n"; // std::cout lives in the iostream library
std::cout << "It is very nice to meet you!\n"; // these comments make the code hard to read
std::cout << "Yeah!\n"; // especially when lines are different lengths
在行的右边添加注释会使代码和注释难以阅读,尤其是在行很长的情况下。
如果行很短,则注释可以简单地对齐(通常对齐到制表符),如下所示:
std::cout << "Hello world!\n"; // std::cout lives in the iostream library
std::cout << "It is very nice to meet you!\n"; // this is much easier to read
std::cout << "Yeah!\n"; // don't you think so?
但是,如果行很长,则在右边添加注释会使行更很长。在这种情况下,可以把单行注释挪到要注释的行的上方:
1 // std::cout lives in the iostream library
2 std::cout << "Hello world!\n";
3
4 // this is much easier to read
5 std::cout << "It is very nice to meet you!\n";
6
7 // don't you think so?
8 std::cout << "Yeah!\n";
作者注
上面的代码是我们前面见过的程序代码的片段。由于代码片段不是完整的程序,因此无法自行编译。使用代码片段是为了以简洁的方式展示特定的概念。如果您想编译这个代码段,则需要将其变成一个完整的程序才能进行编译。通常,完整的程序代码如下所示:
1 #include <iostream>
2
3 int main()
4 {
5 // Replace this line with the snippet of code you'd like to compile
6
7 return 0;
7 }
多行注释(Multi-line comments)
C++的多行注释用一对/* 和*/表示。这俩符号之间的所有内容都是注释,将被编译器将被忽略。
/* This is a multi-line comment.
This line will be ignored.
So will this one. */
由于符号之间的所有内容都会被忽略,因此您有时会看到程序员以下面这种方式“美化”他们的多行注释:
/* This is a multi-line comment.
* the matching asterisks to the left
* can make this easier to read
*/
多行样式注释之间不能相互嵌套。以下内容将产生不可预料的结果:
/* This is a multi-line /* comment */ this is not inside the comment */
// The above comment ends at the first */, not the second */
当编译器尝试对此进行编译时,它将忽略从第一个/*到第一个*/之间的所有内容。由于“this is not inside the comment */”不被视为注释的一部分,因此编译器将尝试对其进行编译。这明显会导致编译错误。
在这种情况下,语法突出显示功能非常有用,因为不同的颜色会清楚说明上面这段中哪些是注释哪些不是。
警告
不要在多行注释中嵌套多行注释。但将单行注释嵌套在多行注释中是可以的。
正确使用注释
通常,注释应该用于三种场合。首先,对于给定的库、程序或函数,最好使用注释来描述库、程序或函数的功能。这些通常放置在文件或库的顶部,或紧靠在函数之前。例如:
// This program calculates the student's final grade based on his test and homework scores.
// This function uses Newton's method to approximate the root of a given equation.
// The following lines generate a random item based on rarity, level, and a weight factor.
所有这些注释使读者可以很好地了解库、程序或函数的功能,而不必查看实际的代码。这样,用户(可能是其他人,或者是您,比如您尝试重用您以前编写的代码)一眼就能知道该代码是否与他或她想要完成的工作有关。当作为团队的一部分工作时,这一点尤其重要,因为不是每个人都熟悉所有代码。
其次,在上述库、程序或函数中,注释可用于描述内部代码将如何实现其目标。
/* To calculate the final grade, we sum all the weighted midterm and homework scores
and then divide by the number of scores to assign a percentage, which is
used to calculate a letter grade. */
// To generate a random item, we're going to do the following:
// 1) Put all of the items of the desired rarity on a list
// 2) Calculate a probability for each item based on level and weight factor
// 3) Choose a random number
// 4) Figure out which item that random number corresponds to
// 5) Return the appropriate item
这些注释使用户可以了解代码将如何实现其目标,而不必了解每行代码的功能。
第三,在语句级别,应使用注释来描述代码为什么要执行某项操作。用注释来说明语句执行了什么操作是错误的用法。
如果您编写的代码如此复杂,以至于需要用注释来解释一条语句的作用,则可能需要重写该语句,而不是对其进行注释。以下是一些坏行注释和好语句注释的示例。
坏注释:
// Set sight range to 0
sight = 0;
原因:通过查看下面的语句,我们可以直接知道该语句把sight设置为0
好的注释:
// The player just drank a potion of blindness and can not see anything
sight = 0;
原因:看到注释后,我们知道了为什么将玩家的sight设置为0
坏注释:
// Calculate the cost of the items
cost = quantity * 2 * storePrice;
原因:我们可以看到这是一个成本计算,但是不知道为什么数量要乘以2
好的注释:
// We need to multiply quantity by 2 here because they are bought in pairs
cost = quantity * 2 * storePrice;
原因:现在我们知道了该公式的意义。
程序员通常必须在能够解决问题的多种方案之间做出艰难的决定。注释是提醒自己(或告诉其他人)您选择一个方案而不是另一个方案的原因的好方法。
好的注释:
// We decided to use a linked list instead of an array because
// arrays do insertion too slowly.
// We're going to use Newton's method to find the root of a number because
// there is no deterministic way to solve these equations.
最后,注释应该以一种能让不了解这段代码的人也能看懂的方式编写。通常情况下,程序员会说:“很明显能看出这段代码是做什么的!我绝对不会忘记这一点。”你猜怎么了?这不是很明显,您会惊奇地发现自己忘得这么快。您(或其他人)稍后将感谢您以人类的语言写下了代码的What、Why、How。毕竟读取单行代码很容易,但要梳理出它们对于要实现的功能的意义很难。
最佳实践
尽量多地给您的代码添加注释,并总是假设使用您代码的人并不了解这段代码。不要假设您会一直记得这段代码为什么这么写。
作者注
在本系列教程的其余部分中,我们将在代码块内使用注释来引起您对特定事物的注意,或帮助说明事物的工作方式(同时确保程序仍可编译)。精明的读者会注意到,按照以上标准,这些注释中的大多数都是非常严肃的。在阅读本教程的其余部分时,请记住,这些注释是有教育目的的,而不是试图证明好的评论是什么样的。
注释代码
将一行或多行代码转换为注释称为注释代码。这样,可以方便地(暂时)将部分代码排除在编译程序之外。要注释掉一行代码,只需使用//符号将一行代码临时变为注释:
未注释:
std::cout << 1;
注释:
// std::cout << 1;
要注释掉代码块,请在多行代码上使用//,或使用/* */样式注释将代码块临时转换为注释。
未注释:
std::cout << 1;
std::cout << 2;
std::cout << 3;
注释:
// std::cout << 1;
// std::cout << 2;
// std::cout << 3;
或:
/*
std::cout << 1;
std::cout << 2;
std::cout << 3;
*/
您可能有很多原因要这样做:
-
您正在处理尚无法编译的新代码,但此时需要运行该程序。如果出现编译器错误,编译器将不允许您编译代码。注释掉无法编译的代码将使程序得以编译,您从而可以运行它。之后,您可以取消注释代码,然后继续编程。
-
您编写了可以编译但无法正常工作的新代码,并且没有时间来修复它。注释掉这些代码以确保其不会执行,从而避免程序出错,直到您将其修复为止。
-
查找程序错误的来源。如果某个程序未产生预期的结果(或崩溃),有时禁用部分代码以查看是否可以找出导致其无法正常工作的原因很有用。如果您注释掉一行或多行代码,并且您的程序开始按预期运行(或停止崩溃),那么最后注释掉的内容就是问题所在。然后,您就可以调查为什么这些代码会出错。
-
您想要用另一段代码替换一段代码。您可以将原代码注释掉并留在那里以供参考,直到您确定新代码可以正常工作,而不是直接删除原始代码。一旦确定新代码可以正常工作,就可以删除旧的注释掉的代码。如果您无法使用新代码,则可以删除新代码,并取消注释旧代码以恢复到以前的状态。
在开发过程中,注释掉代码是很常见的事情,因此许多IDE都支持注释掉代码选中的部分。
提示
如果您始终使用单行注释作为常规注释,那么可以始终使用多行注释来注释掉您的代码而不会发生冲突。如果您使用多行注释来标记代码,则使用注释注掉代码可能会变得更具挑战性。
如果确实需要注释掉包含多行注释的代码块,则还可以考虑使用#if 0 预处理器指令,我们将在第2.10节“预处理程序简介”中进行讨论。
小结
- 在库、程序或函数级别,使用注释来描述"是什么"
- 在语句级别,使用注释来描述"为什么"
- 在库、程序或函数内部,使用注释描述"怎么做"