在計算機程式設計中，塊（block）或譯為程式區塊、程式碼塊，是將原始碼組織在一起的詞法結構。塊構成自一個或多個和語句。程式語言允許建立塊，包括嵌入其他塊之內的塊，就叫做塊結構程式語言。塊和子程式是結構化程式設計的基礎，結構化所強調的控制結構可以用塊來形成的。 在程式設計中塊的功能，是確使成組的語句被當作如同就是一個語句，限定在一個塊中宣告的物件如變數、過程和函式的詞法作用域，使得它們不衝突於在其他地方用到的同名者。在塊結構程式語言中，在塊外部的物件名字在塊內部是可見的，除非它們被聲明瞭相同名字的物件所遮掩。 歷史 塊結構的想法是在 1950 年代開發最初的期間發展出來的，並形式化於 ALGOL 60 報告中。ALGOL 58 介入了 複合（compound）語句的概念，它只與控制流程有關。在 ALGOL 60 報告 中，介入了塊和作用域的概念。最終在 修訂報告 中，複合語句被定義為：包圍在語句括號 begin 和 end 之間的成序列的語句，形成一個複合語句。塊被定義為：成序列的宣告，跟隨著成序列的語句，並被包圍在 begin 和 end 之間，形成一個塊；所有宣告以這種方式出現在一個塊中，並只在這個塊中有效。塊與複合語句的主要差異是不能從塊外跳轉到塊內的標籤。 語法 塊在不同語言家族中使用不同的語法： ALGOL 語言家族，ALGOL 60 及其後繼者比如 Simula，使用語句括號 begin 和 end 來界定複合語句和塊。ALGOL 68 成為了，偏好使用與 begin 和 end 等價的圓括號 和。 Pascal 語言家族，在 Pascal 中塊就是程式、過程和函式的主體，它細分為六節，前五節中任何一個或多個都可以空無，在最後的語句部份使用關鍵字 begin 和 end 來界定複合語句。 C 語言家族，C 承襲了 BCPL，使用花括號 和 來界定複合語句或塊 。 Lisp 語言家族，Lisp 15 使用具有語法關鍵字 prog 的 S 表示式表示塊 ，而 Maclisp 和 Scheme 使用 let 形式的 S 表示式來表示塊 ，S 表示式是圓括號 和 包圍的字首表示法。 Smalltalk 語言家族，Smalltalk80 和 Self 使用方括號 和 來界定塊。 此外，複合語句界定還可以採用： 越位規則，源於 ISWIM 使用縮排表示塊結構，採用越位規則的語言有 occam、Python 和 Nim 等。 建立控制結構，除了將所控制的語句序列，包圍入複合語句或匿名塊之外，還可以採用其他語法機制： 在 ALGOL 68 中，條件和迭代語句，使用塊首保留字的反寫保留字來終止，比如：IF THEN ELIF THEN ELSE FI 和 FOR FROM TO BY WHILE DO OD。繼承此風格的有：Dijkstra 的守衛命令語言和 Bourne 的 Bourne shell 等。 一些結構化程式語言，如 FORTRAN 77、Modula2、Ada 和 Visual Basic 等，對控制結構加結束關鍵字，比如 Modula2 中的：IF THEN ELSIF THEN ELSE END 和 FOR TO BY DO END。 限制 受 ALGOL 影響的一些語言支援塊，但有著各自的限制： C 家族語言，在塊和複合語句之中不僅支援巢狀入複合語句，還支援嵌入帶有宣告的匿名塊，但不允許宣告。 Pascal 家族語言，在語句部份的複合語句之中，不允許存在帶有宣告的匿名塊，只支援複合語句，用來在 if、while、repeat 等控制語句內組合語句序列。 基本語義 塊的語義是雙重的。首先，它向程式設計者提供了建立任意大和複雜的結構，並把它當作一個單元的一種途徑。其次，它確使程式設計者能限制變數的作用域，有時可以限制已經被聲明瞭的其他物件的作用域。 在早期語言比如 FORTRAN 和 BASIC 中，沒有語句塊或控制結構。直到 1978 年標準化 FORTRAN 77 之前，都沒有 塊狀 IF 語句，要實現按條件選擇，必須訴諸 GOTO 語句。例如下述 FORTRAN 程式碼片段，從僱員工資中分別扣除超出正稅閾值部分的稅款，和超出附加稅閾值部分的附加稅款： C 語言：ANSI 標準 FORTRAN 66 C 初始化要計算的值 PAYSTX FALSE PAYSST FALSE TAX 00 SUPTAX 00 C 如果僱員掙錢小於等於正稅閾值則躍過稅款扣除 IF WAGES LE TAXTHR GOTO 10 PAYSTX TRUE TAX WAGES TAXTHR BASCRT 10 CONTINUE C 如果僱員掙錢小於等於附加稅閾值則躍過附加稅扣除 IF WAGES LE SUPTHR GOTO 20 PAYSST TRUE SUPTAX WAGES SUPTHR SUPRAT 20 CONTINUE TAXED WAGES TAX SUPTAX 程式的邏輯結構不反映在程式碼中，這裡的初始化的值，是後面的有關邏輯判斷為假時所應當設定的值。 塊允許程式設計者把一組語句當作一個單元。例如，在與上述 FORTRAN 程式碼相對應的 Pascal 程式碼片段： 語言：Jensen 與 Wirth 版標準 Pascal if Wages TaxThreshold then begin PaysTax true Tax Wages TaxThreshold TaxRate end else begin PaysTax false Tax 0 end if Wages SupertaxThreshold then begin PaysSupertax true Supertax Wages SupertaxThreshold SupertaxRate end else begin PaysSupertax false Supertax 0 end Taxed Wages Tax Supertax 與上述 FORTRAN 程式碼相比，上例中出現在初始化中的那些預設值，透過複合語句即不帶宣告的塊結構，被分別放置作出有關邏輯判斷的地方。使用塊結構，能明晰程式設計者的意圖，使程式碼的結構更加密切反映出程式設計者的思考；再憑藉某種風格的縮排和駝峰式大小寫增進可讀性，可使程式碼更加容易理解和修改。 在早期語言中，在子例程中變數的作用域遍及整個子例程。假想在一個 Fortran 子例程中，完成了與管理者有關的任務，這裡可能用到叫做 IEMPNO 的一個整數變數，指示作為管理者的僱員的社會安全號碼（SSN）；後來在這個子例程的維護工作中，又增加與下屬們有關的任務，此時程式設計者可能不經意間使用同名變數 IEMPNO，指示了作為這個管理者的下屬的僱員的 SSN，這就會導致一個難於跟蹤的缺陷。 塊結構使得程式設計者能夠容易地將作用域控制到細微級別。例如完成有關僱員任務的 Scheme 程式碼片段： 語言：R5RS 標準 Scheme let empno ssnof employeename when ismanager empno when 已列入 R7RSsmall 標準 let employeelist underlingsof empno display format 是 SRFI28 和 SRFI48 規定的字串格式化過程 format a has a employees working under him employeename length employeelist foreach lambda empno display format Name a role a nameof empno roleof empno employeelist 這裡在外層透過繫結宏 let 將管理者的 SSN 繫結到了區域性變數 empno，在其形成的塊的作用域中列出管理者的僱員名字和他的下屬數目；隨後透過 foreach 高階函式，將他所有下屬的 SSN 逐個繫結到匿名函式 lambda 的形式引數 empno 上，執行此匿名函式列出這個下屬的名字和角色；這個形式引數的作用域是此匿名函式的主體，它與其外層的區域性變數，識別符號重名但不相互影響。在實踐中，出於清晰性的考慮，程式設計者更可能選取明顯不同的變數名字，但是即使名字選取存在重複，也難以在不經意間介入一個缺陷。在基於 S 表示式的語言中，經常見到大量的巢狀圓括號，故而其程式碼必須採用良好的縮排。 提升 在一些語言中，變數可以宣告為有函式作用域即使它位於函式的內嵌塊之中。例如在 JavaScript 中，變數應當總是在使用之前被宣告，它曾經允許賦值到未宣告變數，會為此建立為未宣告的全域性變數，這在 strict 模態下是個錯誤。以 var 宣告的變數有函式作用域，而非以 let 或 const 宣告的變數可從屬的塊作用域。以 var 宣告的變數會被提升（hoist），這意味著可以在這個函式的作用域內任何地方提及這個變數，即使還未觸及到它的宣告，從而可以將 var 宣告視為被提舉（lift）到它所在函式的頂部或全域性作用域。但是如果在其宣告之前訪問了一個變數，這個變數的值總是未指定的。 參見 基本塊 作用域 控制流程 閉包 計算機科學 引用 Category 程式架構