註解 (程式設計)

計算機語言中,注釋計算機語言的一個重要組成部分,用於在源代碼中解釋代碼的功用,可以增強程序的可讀性,可維護性,或者用於在源代碼中處理不需運行的代碼段,來調試程序的功能執行。

包含注釋的 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).