注释
1. 定义
注释的作用是在代码内写文档供人类阅读;编译器会忽略注释(技术上,是把注释替换成一个空格)。
2. 分类
- 行内注释:单行注释以
//开始:编译器会忽略从//开始到行末的所有字符。 - 块注释:多行注释以
/*开始,以*/结束。编译器会忽略从/*开始到*/结束的所有字符,包括/*和*/。
3. 示例
c
#include <stdio.h>
int main(void) {
// 这是行内注释
/* 这是块注释 */
puts("Hello World 01");
// puts("Hello World 02");
/*
puts("Hello World 03");
puts("Hello World 04");
puts("Hello World 05");
*/
/*
* 为了整齐美观,也可以这样写:
* puts("Hello World 06");
* puts("Hello World 07");
* puts("Hello World 08");
*/
return 0;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
可能的输出:
bash
Hello World 01
4. 语法边界
块注释不能嵌套,也就是 /* ... /* ... */ ... */ 这种写法不合法。需要临时屏蔽大段代码时,通常应借助条件编译(例如 #if 0 ... #endif),而不是依赖嵌套注释。
5. 写作建议
注释应解释“为什么这样写”,而不是复述“这行代码在做什么”。当代码本身已经很直白时,重复性的注释反而会增加噪声;当行为有前提、约束或平台边界时,再用注释补充上下文,信息密度会更高。
6. 注释与条件编译的分工
注释用于说明语义,条件编译用于控制代码是否参与翻译,这两者不应互相替代。临时屏蔽某段代码时,#if 0 ... #endif 通常比大块注释更稳妥,也更不容易因为注释边界写错而破坏源码结构。
c
#if 0
legacy_path();
#endif1
2
3
2
3
运行结果:该代码块主要用于语法或结构说明,单独运行通常无终端输出。
当这段逻辑重新启用时,只需要调整条件,不需要重新编辑大量注释符号。
7. 注释与宏定义的边界
宏定义里若使用续行反斜杠,注释位置需要格外小心。尤其是 // 行注释会吞掉本行后续内容,可能让本应继续到下一行的宏提前结束。处理多行宏时,通常应优先使用块注释并保持每一行末尾的续行符清晰可见。
c
#define LOG_IF(cond, msg) \
do { \
if (cond) { \
/* 统一日志出口 */ \
puts(msg); \
} \
} while (0)1
2
3
4
5
6
7
2
3
4
5
6
7
可能的输出(示例):
bash
<输出与输入或平台相关,请以实际运行为准>
8. 让注释跟随约束而不是实现细节
实现细节会频繁变化,约束和前提通常更稳定。注释若只描述“这行做了什么”,很快就会过期;若描述“为什么必须这么做、依赖什么输入条件、失败时保证什么状态”,就更容易长期保持有效。这也是注释真正提升可维护性的关键。