程序設計中,縮進風格indent style)是管理代碼塊縮進以表達程序結構的一種約定。本條目主要討論自由形式語言,例如C及其後裔,但這也可以(並經常)適用於大多數其他編程語言(尤其是花括號編程語言英語Curly bracket programming language),其中的空白字符則並不重要。縮進風格是代碼風格的一個方面。

縮進在大多數編程語言中不是必要條件,而只是作為輔助符號英語Secondary notation。不過,縮進有助於更好地向人類閱讀者表達程序的結構。尤其是用於澄清控制流程結構(例如條件或循環)與其內部、外部代碼之間的關係。不過,部分語言(例如Pythonoccam)使用縮進而非花括號或關鍵詞來確定結構,這被稱為越位規則。在這種語言中,縮進對編譯器或解釋器有意義,而不僅僅是清晰度或風格問題。

花括號位置

編輯

縮進風格的主要區別在於複合語句的花括號({...})的位置,這通常是為涵蓋一個控制聲明(ifwhilefor...)。下表展示了本條目中討論的所有風格的所在位置。為了一致性,縮進深度(字符數)統一使用4個空格表示,這未考慮各風格中首選的縮進深度。

花括號位置 風格
while (x == y) {
    something();
    somethingelse();
}
K&R及變種:

1TBSStroustrupLinux內核BSD KNF

while (x == y)
{
    something();
    somethingelse();
}
Allman
while (x == y)
  {
    something();
    somethingelse();
  }
GNU
while (x == y)
    {
    something();
    somethingelse();
    }
Whitesmiths
while (x == y)
{   something();
    somethingelse();
}
Horstmann
while (x == y)
{   something();
    somethingelse(); }
Pico
while (x == y) {
    something();
    somethingelse();
    }
Ratliff
while (x == y) {
    something();
    somethingelse(); }
Lisp

制表符、空格及縮進尺寸

編輯

縮進的尺寸通常與風格無關。許多早期程序使用制表符來縮進,從而簡化輸入和節約源代碼文件的大小。Unix編輯器通常將制表符視為等同八個字符,而MacintoshWindows環境將它視作四個字符[來源請求],這使代碼在各環境間交換時產生一種混亂。現代的編程編輯器通常可以設置任意的縮進尺寸,並會插入適當的制表符與空格。對Ruby、許多shell腳本語言和某些形式的HTML格式,通常為每個縮進級別使用兩個空格。[1]

使用制表符還是空格作為縮進字符是編程界的一項持續爭論。傑米·加文斯基等一些程序員認為空格而非制表符有助增加跨平台可移植性[2]而如WordPress編碼規範的作者則認為制表符增加了可移植性。[3]

工具

編輯

目前已有許多計算機程序可以自動校正縮進風格(依照程序作者或用戶的偏好)以及制表符表示的縮進長度。其中很著名的一個是indent,這個程序包含在許多類Unix操作系統中。

Emacs中,有多種命令可用於自動解決縮進問題。

Elastic tabstops是一種需要文本編輯器支持的制表風格,當塊中的一行的長度改變時,整個文本塊將自動對齊。

風格

編輯

K&R風格常在C、C++以及其他花括號編程語言英語Curly brace programming language中使用。在布萊恩·柯林漢丹尼斯·里奇的《C程序設計語言》一書中也有使用。它起源於Kernighan和Plauger的《編程風格的元素英語The Elements of Programming Style》及軟件工具。


變種:1TBS (OTBS)

編輯

變種:Java

編輯

變種:Stroustrup

編輯

變種:Linux內核

編輯

變種:BSD KNF

編輯

阿爾曼風格

編輯

變種:Allman-8

編輯

Whitesmiths style

編輯

GNU風格

編輯

Horstmann風格

編輯

Pico風格

編輯

Ratliff風格

編輯

Lisp風格

編輯

Haskell風格

編輯

Haskell是一種花括號可選的語言[4],也就是說,下面的兩組代碼在語義上是相等的:

braceless = do
  text <- getContents
  let
    firstWord = head $ words text
    bigWord = map toUpper firstWord
  putStrLn bigWord
braceful = do
  { text <- getContents
  ; let
      { firstWord = head $ words text
      ; bigWord = map toUpper firstWord
      }
  ; putStrLn bigWord
  }

通常,procedural do的段落和一般程序文本會省略花括號和分號,但這種風格通常用於由一對括號或花括號組成的列表、記錄或其他句法元素,並用逗號或分號分隔。[5]

其他考慮

編輯

丟失塊蹤跡

編輯

在某些情況下存在着丟失塊邊界的軌跡的風險。這通常在包含許多複雜語句的大量代碼中看到,這些複合語句嵌套了許多層的縮進。當程序員滾動到一大堆嵌套語句的底部時,他可能已經忘記了哪些控制語句轉到哪裡。不過,過長的代碼也可能有其他原因, 諸如過於複雜,面對這個問題的程序員可能會考慮代碼重構以期待它在未來有更好的體驗。

for (int i = 0; i < total; i++) {
    foo(bar);
} //for (i)
if (x < 0) {
   bar(foo);
} //if (x < 0)

聲明的插入

編輯

在使用標準的Unix行編輯器ed時,K&R風格能防止一個常見的錯誤。在控制語句與循環塊的開啟花括號之間錯誤地插入的語句將使循環體變為單次執行。

for (int i = 0; i < 10; i++)
    whoops(bar);   /* repeated 10 times, with i from 0 to 9 */
{
    only_once();   /* Programmer intended this to be done 10 times */
} //for (i) <-- This comment is no longer valid, and is very misleading!

K&R風格通過將控制語句和開啟括號保持在同一行來避免此問題。

參見

編輯

參考資料

編輯
  1. ^ Detecting Code Indentation. 2014-09-08 [2017-07-28]. (原始內容存檔於2020-11-12). 
  2. ^ Zawinski, Jamie. Tabs versus Spaces: An Eternal Holy War. 2000 [2016-06-06]. (原始內容存檔於2018-06-12). 
  3. ^ WordPress Coding Standards. [2016-06-06]. (原始內容存檔於2021-03-24). 
  4. ^ The Haskell 98 Report. [2016-03-03]. (原始內容存檔於2021-04-11). 
  5. ^ Lipovača, Miran. Making Our Own Types and Typeclasses. [2016-02-03]. (原始內容存檔於2021-04-13). 

外部連結

編輯