註解 (程式設計)

電腦語言中,註解電腦語言的一個重要組成部分,用於在原始碼中解釋程式碼的功用,可以增強程式的可讀性,可維護性,或者用於在原始碼中處理不需執行的程式碼段,來除錯程式的功能執行。

包含註解的 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).