do-until 敘述(The do-until Statement)
do-until
敘述與 while
敘述類似,但他是重複執行指定程式碼直到指定的條件變為 true
,另外他測試 condition
的地方是放在結尾,所以 body
的程式碼至少會被執行一次。do-until
敘述中 condition
的測試方式與 if
敘述相同,若其值為 0
則視為 false
,否則視為 true
,若為向量或矩陣,則只有當向量或矩陣不是空矩陣且所有的元素值都不是 0
時,才視為 true
,否則視為 false
。
do-until
的使用方式為:
do body until (condition)
body
可以是一個或多個敘述,而 condition
則用來控制要執行幾次 body
。
下面的範例會產生一個含有 Fibonacci 數列的變數 fib
:
fib = ones (1, 10); i = 2; do i++; fib (i) = fib (i-1) + fib (i-2); until (i == 10)
在 do
與 body
之間可以不需要換行,不過除了很簡單的迴圈之外,使用換行可以使程式碼更容易閱讀。
for 敘述(The for Statement)
for 敘述基本用法
for
敘述可以明確的指定迴圈的執行次數,其使用方式為:
for var = expression body endfor
其中 body
可以是一個或多個敘述,expression
可以是任何的算式,而 var
則可以是很多形式,最常見的就是一個變數,但若 expression
傳回的是資料結構(structure),則 var
就必須要指定為一個含有兩個元素的向量。
在 for
敘述中的指定運算子與 Octave 中一般的指定運算子有些不同,它不會一次將 expression
的值整個指定給 var
,而是依序將 expression
的每一個行(column)指定給 var
。若 expression
是範圍(range)、列向量(row vector)或純量(scalar),則每一次指定給 var
的值會是一個純量;若 expression
是行向量(column vector)或矩陣,則每一次指定給 var
的值會是一個行向量。
下面的範例示範如何使用 for
迴圈建立 Fibonacci 數列:
fib = ones (1, 10); for i = 3:10 fib (i) = fib (i-1) + fib (i-2); endfor
這個 for
迴圈首先會執行 3:10
而得到一個範圍,然後將此範圍的第一個值(也就是 3
)指定給 i
,接著執行 body
部分的程式碼,執行完之後又將此範圍中的下一個值指定給 i
,然後再繼續執行 body
,這樣重複執行到範圍中所有的元素都指定完為止。
在 Octave 中可以使用 for
迴圈存取矩陣中的元素,例如:
for i = [1,3;2,4] i endfor
這個範例中 i
會依序被指定為矩陣的行向量,輸出為
i = 1 2 i = 3 4
巢狀陣列也可以這樣使用:
for i = {1,"two";"three",4} i endfor
輸出為
i = { [1,1] = 1 [2,1] = three } i = { [1,1] = two [2,1] = 4 }
這樣的用法可以拓展至更高維度的陣列上:
a = [1,3;2,4]; b = cat(3, a, 2*a); for i = b i endfor
這個範例中,矩陣 b
會以 reshape (b, rows(b), prod(size(b)(2:end)))
的方式被轉換成二維的矩陣,然後再以一般矩陣的方式進行迴圈的運算,其輸出為
i = 1 2 i = 3 4 i = 2 4 i = 6 8
雖然所有的 for
迴圈都可以改寫成 while
迴圈,但由於這兩種迴圈各適用於不同的情況,因此 Octave 對這兩個迴圈都支援。
資料結構使用迴圈(Looping Over Structure Elements)
資料結構(structure)可以使用特殊的 for
迴圈來存取:
for [ val, key ] = expression body endfor
在這種 for
迴圈中,expression
必須指定為一個資料結構,而其中的欄位名稱與對應的值會依序被指定為 val
與 key
,例如:
x.a = 1; x.b = [1, 2; 3, 4]; x.c = "string"; for [val, key] = x key val endfor
輸出為
key = a val = 1 key = b val = 1 2 3 4 key = c val = string
使用 for
存取資料結構時,其元素的順序是不固定的,若需要以指定的順序存取其中的元素,則必須以 fieldnames()
函數取得欄位名稱後自行排序。