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)

dobody 之間可以不需要換行,不過除了很簡單的迴圈之外,使用換行可以使程式碼更容易閱讀。

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 必須指定為一個資料結構,而其中的欄位名稱與對應的值會依序被指定為 valkey,例如:

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() 函數取得欄位名稱後自行排序。