指定敘述

在程序設計中，指定敘述（assignment statement）-{zh-cn:，;zh-tw:，又譯指定指述，}-會將一個特定的值設定到某個特定的儲存位址去，這個位置被標記成一個特定的變數名稱。換句話說，這個敘述會複製一個值到某個特定變數中。在多數的指令式程式語言中，這種敘述是其中最基礎的結構。
指定敘述的通用表示方法通常是 x = expr（這種表示法最早源自1949年–1951年時的，因為1957年首版的Fortran與C語言而廣為人知），另一種形式則為 x := expr（這種形式最早來自ALGOL 58，因為Pascal而盛行）。在這兩種表示法之外，仍然存在許多其他的形式。
對多數的指令式程式語言來說，指定敘述允許某個特定變數，在其生命週期與作用域之中，可以被指定為不同的值，或是重複被-{指定}-值。

**語義**
在指令式編程中，隨著時間改變，不同的值被關聯到某個特定的變數名稱上。變數是數值的容器。可以先指派變數為某個值，在之後再用另一個值來加以取代。在這種模型中，程式的運作，是透過每次成功的指定敘述，來改變其狀態。指令式程式語言，倚靠指定敘述來進行迭代。在最低的層級中，指定敘述是以組合語言指令，如 MOVE 或 STORE來實作。
以C語言為例，下列的程式碼段落可以作為指定敘述的例子：
int x = 10; 
float y;
x = 23;
y = 32.4f;
在第一行程式碼中，變數x先被宣告為int型別，之後將數值10指定給它。在第二行，變數y被宣告為float型別，但沒有-{指定}-值。在第三行，變數x被重新指定為數值23。在第四行中，變數y被指定為浮點數值32.4f。

**單賦值**
任何改變現存值的賦值（比如x := x + 1），在純函數式語言中都是不允許的。在現今的函數式編程中，賦值是被勸阻的，用以支持也叫做“初始化”的單賦值。單賦值是名字綁定的用例，不同於本文其他部分描述的賦值之處在於，它只能做一次，通常是在變量被創建的時候，不允許後續的重新賦值。
表達式的求值，如果不改變機器的可察見狀態，並且對相同的輸入產生相同的值，就沒有副作用。指令式賦值，在銷燬舊值並使之不可獲得時，在將舊值替代為新值時，就可能介入了副作用；為此在LISP和函數式編程中，這被稱為“破壞性”（destructive）賦值，類似於“破壞性更新”。
在純函數式語言比如Haskell中，單賦值是賦值的唯一形式，這裡沒有在指令式語言意義上的變量，而是命名的常量值，並具有可能的合成（compoud）本性，即它們的元素"在需要時"被逐步的定義。純函數式編程和與之於此共通的數據流程編程，由於值之間相互獨立，可以提供在並行計算上的優勢，它避免了順序的一時一步執行的馮·諾伊曼瓶頸。
非純函數式語言，同時提供了單賦值和真賦值（儘管相比指令式編程語言而言真賦值典型的較少使用）。例如，在Scheme中，單賦值（通過let），和真賦值（通過set!），二者都可以用於所有變量上，並提供專門的原語（primitive）用於在列表、向量、字符串等之內做破壞性更新。在OCaml中，只有單賦值，通過let name = value語法，被允許用於變量；而破壞性更新，可通過單獨的算符，用於數組的元素和字符串，還可用於已經被編程者顯式聲明為可變（意味著能夠在其初始化聲明之後被變更）的記錄字段和對象。
使用單賦值的函數式編程語言，包括Clojure（針對數據結構，而非變量）、Erlang（相比Haskell，它接受多次賦值，如果值相等的話）、F#、Haskell、Lava、OCaml、Oz（對用數據流變量，而非cell）、Racket（對於一些數據結構如列表，而非符號）、SASL、Scala（對於變量）、SISAL、Standard ML。非回溯的Prolog代碼可以被看作“明顯的”單賦值，這裡明顯的含義為，它的（命名）變量可以顯式的處在未賦值狀態，或只能準確的被設置一次。相反的，在Haskell中，沒有未賦值變量，而所有變量可以看作在創建時就被隱式的設定了它的值（更精確的說是設置了計算對象在“在需要時”產生它的值）。

**指定語句的回傳值**
在一些編程語言中，指定敘述的整個語句可能會傳回某種型別的一個值，而在其它語言中則不會。
在 C 編程語言中指定語句只會單純返回-{指定}-值，而允許這樣子的片語 x = y = a，其中指定語句 y = a 返回值 a，然後將值指定到 x。在諸如 while ((ch = getchar()) != EOF) {…} 的語句中，函數的返回值可用於控制迴圈，同時將相同的值指定給變量 ch。
在其它編程語言中例如 Scheme，指定語句的返回值是未定義的，而且這些片語無效。
在 Haskell 中沒有變量指定；但類似於指定的操作（如分配給數組的字段或可變數據結構的字段）通常以 unit型別為單位進行求值，unit 型別以 ()表示。這種型別只有一個可能的值，因此不包含任何信息。它通常是純粹為了副作用而評估的表達型別。

**賦值的變體形式**
特定使用模式也非常常見，因此經常有支持它們的特殊語法。這些主要是減少源代碼冗長的語法糖，但也能輔助代碼讀者理解編程者的意圖，並提供給編譯器進行可能的優化的線索。

**增廣賦值**
所賦予的值依賴於先前的值是很常見的，很多指令式語言，尤其是C及其主要派生者，提供了叫做增廣賦值的特殊算符，比如*=，則a = 2*a可以轉而寫為a *= 2。

**鏈式賦值**
語句如w = x = y = z叫做“鏈式賦值”，其中z的被賦給多個變量w、x和y。鏈式賦值經常用來初始化多個變量，比如a = b = c = d = f = 0。

**並行賦值**
一些編程語言，比如APL、Common Lisp、Go、JavaScript（自從1.7）、Lua、Maple、occam 2Broken anchor|date=2025-05-12|bot=User:Cewbot/log/20201008/configuration|target_link=occam#occam 2|reason= 錨點（occam 2）已被刪除。|diff_id=59487108、Perl、PHP、Python、REBOL、Ruby、Windows PowerShell，允許多個變量被並行的賦值，語法如下：
a, b := 0, 1
它同時賦值0到a和1到b。這經常叫做並行（parallel）賦值；它是CPL語言於1963年介入的，當時名字叫做同時（simultaneous）賦值，有時也叫做多（multiple）賦值，但這在與單（single）賦值一起用時會產生混淆，因為它們不是對比的。如果賦值的右手側是一個單一變量（比如一個數組或結構），這個特徵就叫做解包（unpacking）或解構（destructuring）賦值：
var list := {0, 1}
a, b := list
這個列表將被解包使得賦值0至a和1至b。進一步的：
a, b := b, a
對換a和b的值。在沒有並行賦值的語言中，這必須通過臨時變量來書寫：
var t := a
a := b
b := t
因為a := b; b := a將把a和b二者都賦值為b最初的值。
一些語言，比如Go和Python，將並行賦值、元組和自動元組解包結合起來，允許從一個單一函數返回多個值，比如如下Python的例子：
def f():
return 1, 2
a, b = f()
而其他語言，比如C#，要求使用圓括號的顯式元組構造和解構，如下面例子這樣：
(a, b) = (b, a);
(string, int) f() => ("foo", 1);
var (a, b) = f();
這提供了從一個函數返回多個值要使用輸出參數的一種替代方式。這最早見於CLU語言（1974年），而CLU推動了一般的並行賦值變得流行。
在C和C++中，逗號運算符，在允許多個賦值出現在一個單一語句上類似於並行賦值，寫a = 1, b = 2替代a, b = 1, 2。這主要用在for循環中，在其他語言比如Go中，被替代為並行賦值。但是上述C++代碼不確保完全的同時性，因為代碼a = b, b = a+1的右側項是在左側項之後運算的。在語言如Python中，a, b = b, a+1將併發的賦值兩個變量，使用最初的a的值來計算新b的值.

**指定與等式符號**

**標記法**
複製分配的兩個最常見的表示形式是等號（=）和冒號等於（:=）。這兩種形式都可以在語義上表示賦值語句或賦值運算符（它也具有值），這取決於語言用法。
其他可能性包括左箭頭或關鍵字，但還有其他更罕見的變體：
數學偽代碼分配通常用左箭頭表示。有些平臺將表達式放在左側，變量放在右側：
一些面向運算式的語言比如 Lisp 和 Tcl，對所有語句（包括賦值）統一使用前綴（或後綴）語法。

**另見**
 設定運算子- Operator (programming)- 名字綁定- 合一- 不可變對象- const (computer programming)

**註釋==