指定算式(Assignment Expressions)

指定算式(Assignment Expressions)是將一個值指定給一個變數,例如將一個數值 1 指定給變數 z

z = 1

執行這個算式之後,變數 z 的原本的值會被 1 取代,這裡的等號(=)稱為指定運算子。指定算式亦可指定字串,例如:

s = "test string"

大部分的運算子(例如加法運算子)只會根據運算元計算一個傳回值,而不會改變運算元原本的值,若是忽略其傳回值,則運算元等於沒有作用,但指定運算子則不同,即便忽略其傳回值,他還是會改變變數中的值,這個稱為運算子的邊際效應(side effect)。

指定運算子的左邊可以是變數(請參考變數)、矩陣的元素(請參考索引算式)或傳回值的逗點分隔序列(請參考呼叫函數),這些統稱作 lvalue,意思是這些都可以放在指定運算子的左邊;而在指定運算子的右邊則可以是任何的算式,這個算式所產生的值會被指定為指定運算子左邊的變數、矩陣元素或逗點分隔序列的值。

在 Octave 中的變數並沒有固定的資料類型,變數的類型是依據其目前所儲存的資料而定,例如:

foo = 1
foo = "bar"

第一行算式將變數 foo 指定為數值 1,而第二行將 foo 指定為字串 "bar" 時,之前的數值就會被覆蓋掉。

若將一個純量指定給矩陣中的一部分元素,則會將每個元素指定為此純量的值,例如:

A = ones(3);
A(:, 2) = 5

這會將矩陣 A 第二行的每一個元素都指定為 5,輸出為:

A =

   1   5   1
   1   5   1
   1   5   1

若指定為空矩陣,則可以刪除矩陣的行或列(請參考矩陣),例如:

A = [1, 2; 3, 4; 5, 6];
A (2, :) = []

這會將矩陣 A 的第二列刪除,輸出為

A =

   1   2
   5   6
A = [1, 2, 3, 4, 5; 6, 7, 8, 9, 10; 11, 12, 13, 14, 15];
A(:, 1:2:5) = []

這會將矩陣 A 的第一、三、五列刪除,輸出為

A =

    2    4
    7    9
   12   14

指定算式也有傳回值,例如 z = 1 的傳回值就是 1,使用這個特性可以將多個指定算式合併成一個:

x = y = z = 0

這個算式首先將 z 設為 0,而後將 z = 0 的傳回值(其值為 0)設定給 y,最後將 y = z = 0 的傳回值(其值為 0)設定給 x,所以最後 xyz 皆被設為 0。這樣的寫法也可以用於逗點分隔序列,例如:

[a, b, c] = [u, s, v] = svd (a)

這樣的寫法等同於

[u, s, v] = svd (a)
a = u
b = s
c = v

使用這樣的寫法,每個逗點分隔序列不需要有相同個數的變數,例如:

[a, b] = [u, s, v] = svd (a)

這樣的寫法也是可以的,其作用等同於

[u, s, v] = svd (a)
a = u
b = s

位於指定運算子左邊的逗點分隔序列的變數個數不可以多於右邊的個數,否則會產生錯誤,例如:

[a, b, c, d] = [u, s, v] = svd (a);

這樣 Octave 就會產生錯誤:

error: element number 4 undefined in return list

在一般程式設計中有一個很常用的算式就是將某個變數加上一個數值,例如將變數 x 加上 2:

x = x + 2;

這種算式可以使用 += 運算子改寫成更精簡的寫法:

x += 2;

類似的用法也可以用於其他的運算子上:

一般用法 簡潔用法
x = x + 2 x += 2
x = x - 2 x -= 2
x = x * 2 x *= 2
x = x / 2 x /= 2
a *= b + 1 是等同於 a = a * (b + 1) 不是 a = a * b + 1

指定算式可以用於任何一般算式可以使用的地方,例如 x != (y = 1) 會將 y 指定為 1 並測試 x 是否不等於 1,雖然 Octave 允許這樣的寫法,但這樣寫會造成程式閱讀上的困難,除非是用於只使用一次的程式,否則最好避免以這種不好閱讀的方式撰寫程式。