註解 (程式設計)

计算机语言中,注释计算机语言的一个重要组成部分,用于在源代码中解释代码的功用,可以增强程序的可读性,可维护性,或者用于在源代码中处理不需运行的代码段,来调试程序的功能执行。

包含注释的 Arduino 代码片段

注释在随源代码进入预处理器编译器处理后会被移除,不会在目标代码中保留其相关信息。

使用

怎么用注释是一个备受争论的论题,观点是各种各样的,有时候甚至观点是正相反的。写法也是各种各样,有时候意见也是存在矛盾的。

代码设计和审查

注释可以用于提供伪代码的大纲,并根据该大纲编写代码。通过这种形式,代码的逻辑会更加清晰。

/* 反向循环所有从服务获取的元素
(他们应该按照时间顺序执行)*/
for (i = (numElementsReturned - 1); i >= 0; i--){
    /* 处理每一个元素里的数据 */
    updatePattern(i, returnedElements[i]);
}

如果在提交代码时,注释没有被删除,那么代码审查者可以根据注释比较代码和意图的拟合度。一个常见的误解——理解代码想要做什么是很简单的事情。

代码描述

注释可用于代码内容的总结、表达开发者的意图。持该观点的学者认为,用更为简单的英语去解释代码是多余的。 需要重新解释地代码,可能意味是候代码太复杂,这时候需要去重写或者重命名。

“不要去解释说明质量低下的代码,应该去重写。”[1]
“好的注释不应该去重复代码的内容、解释代码,而是应该去解释它的意图。你应该尝试在一个高的维度,将代码抽象出来,并为此说明。”[2]

注释也可用于解释一个代码块有什么缺陷,为什么不是最好的方案。这对项目相当紧张、修正bug尤其有效。例如:

' Second variable dim because of server errors produced when reuse form data. No
' documentation available on server behavior issue, so just coding around it.
vtx = server.mappath("local settings")

值得注意的是,上述内容是针对英语国家的程序员。而在非英语国家里,通过当地语言去解释代码、翻译代码的意思,这种行为是很常见的,也普遍被接受的。

算法描述

比如,下面程序将增加一个注释来解释为什么插入排序没有被快速排序所替代,即使理论上前者比后者更慢。这将写为如下:

 list = [f (b), f (b), f (c), f (d), f (a), ...];
 // Need a stable sort. Besides, the performance really does not matter.
 insertion_sort (list);

元数据和资源

在注释中,可以插入各种资源和元数据

  • 常见的资源有:图标、流程图、版权。
  • 常见的元数据有:维护者、第一版的时间、编辑者、相关文档的链接等。

下面是Spring框架中的一段注释,用于表达版权。

/*
 * Copyright 2002-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

许多代码维护者会将指导(元数据)放到注释中,帮助读者更好的阅读,并提供反馈途径。但值得一提,随着Git等版本管理器的流行,元数据作为指导的功能也被部分代替了,如:GIt能记录第一版代码、代码创作者、修改者等信息。

调试

程序员常用的技巧之一,通过暂时把代码块注释的方式,让部分代码不运行。程序员通过该方式,寻找代码bug的位置。

文档自动生成

一些开发工具通过注释来生成文档。如java程序通过javadoc, c/c++等通过doxygen生成文档。

功能代码

作为代码的一部分被使用。如:条件注释Shebang

种类与格式

注释可分类为:

  • 风格(行/块)
  • 解释规则(忽略/插入/内存存储)
  • 递归(支持/不支持)

行注释

行注释通过使用换行'\n'字符来指示注释结束,以及使用标记来开始一条注释。例:

符号 语言
C Fortran 77; 'C'必须在一行的第一个字符。
REM BASIC, COMMAND.COM
# bash, Cobra英语Cobra (programming language)PerlPythonRubyWindows PowerShellPHPMaple
% TeX, Prolog, MATLAB[3], Erlang, S-Lang (计算机语言)英语S-LangVisual Prolog
{} Pascal
// ActionScriptC99C++Objective-CSwiftC#Go, Object Pascal (Delphi),JavaJavaScriptPHP
' Visual BasicVBScriptREALbasic
! Fortran, Basic Plus
; AutoHotkeyAutoitLispScheme, many assemblers
-- EuphoriaHaskellSQLAdaAppleScriptEiffelLuaVHDL
* COBOL, many assemblers
|| Curl
" Vim脚本
\ Forth
:: 批处理[4]

块注释

块注释通过定义一个注释开始和一个注释结束标记来使用。在上下文中,空格換行字符不作为区分标志。例:

符号 语言
¢ ~ ¢, # ~ #, co ~ co, comment ~ comment ALGOL 68
/* */ ActionScript, AutoHotkey, C, C++, Objective-C, Swift, C#, Go, Java, JavaScript, PHP, PL/I, SQL, Visual Prolog, CSS
/# #/ Cobra
""" """ Python, Ruby[註 1]
''' ''' Python[註 1]
=begin =cut Perl
=begin =end Ruby
#<tag> #</tag> S-Lang
{- -} Haskell
(* *) Object Pascal (Delphi),ML, Mathematica, Pascal, Applescript, OCaml, Maple
{ } Object Pascal (Delphi),Pascal
<!-- --> HTMLXML
|# #| Curl
%{ %} MATLAB[3]
#| |# Lisp
--[[ ]] Lua
#if 0

#endif

C语言\C++

注释

  1. ^ 1.0 1.1 More precisely, the quoted text forms a string literal.

参考文献

  1. ^ "Don't document bad code – rewrite it." The Elements of Programming Style, Kernighan & Plauger
  2. ^ "Good comments don't repeat the code or explain it. They clarify its intent. Comments should explain, at a higher level of abstraction than the code, what you're trying to do." Code Complete, McConnell
  3. ^ 3.0 3.1 Add Comments to Code - MATLAB & Simulink. www.mathworks.com. [2022-06-22]. (原始内容存档于2022-05-30). 
  4. ^ Rem - Comment - Windows CMD. SS64.com. [2010-06-15]. (原始内容存档于2021-04-19).