多重傳回值(Multiple Return Values)
Octave 的函數與一般程式語言函數有一個很大的差異,Octave 的函數可以有一個以上的傳回值,其使用方式為:
function [ret-list] = name (arg-list) body endfunction
其中 name
、 body
與 arg-list
與前面提到的函數用法相同,而 ret-list
是一個逗點分隔序列,其包含多個從此函數傳回的變數名稱,此逗點分隔序列中至少要包含一個元素,若其只包含一個元素,其效果就與前面介紹的單一傳回值的函數相同。
下面這個函數會傳會一個向量中的最大值與其出現的位置:
function [max, idx] = vmax (v) idx = 1; max = v (idx); for i = 2:length (v) if (v (i) > max) max = v (i); idx = i; endif endfor endfunction
這個例子中也可以將兩個傳回值合併成一個向量傳回,但這個方式並不適用每一種情況,例如在每個傳回值有不同的維度時,就很難合併成一個向量,另外使用多重傳回值的方式,可以為每個傳回值命名,使用起來也較為方便。
在 Octave 的函數中,有一個內建的 nargout
變數,其會儲存呼叫此函數時,所要求的傳回值個數,這個變數會自動初始化,就像 nargin
一樣,這個功能可以讓函數依照不同的輸出參數而有不同的功能,例如內建的 svd()
與 lu()
函數就是這樣的函數。
ans
變數時,nargout
不會將這個 ans
變數計算在內,此時的 nargout
的值為 0
。函數的多個傳回值中可以只設定其中一部分的值,但這樣會出現一些警告訊息,例如:
function [x, y, z] = f () x = 1; z = 2; endfunction
執行 f()
[a, b, c] = f ()
輸出為
warning: f: some elements in list of return values are undefined a = 1 b = [](0x0) c = 2
沒有被設定的輸出參數,預設為空矩陣。
nargout () nargout (fcn_name)
在一個函數中呼叫 nargout()
函數可以傳回呼叫此函數時所要求的傳回值個數;nargout(fcn_name)
函數會傳回函數 fcn_name
最大的傳回值個數,若傳回 -1
則表示此函數可以傳回不固定個數的傳回值。例如:
f()
若這樣呼叫 f()
函數,則在 f()
函數中,nargout()
的值為 0
,而
[s, t] = f ()
若是這樣呼叫 f()
函數,則在 f()
函數中 nargout()
的值為 2
。
nargout()
函數只適用於函數中,若是在最上層的命列呼叫,則會產生錯誤。
msgstr = nargchk (minargs, maxargs, nargs) msgstr = nargchk (minargs, maxargs, nargs, "string") msgstruct = nargchk (minargs, maxargs, nargs, "struct")
nargchk()
函數可用來檢查函數在呼叫時,是否有傳入正確個數的參數,若傳入的參數個數不正確,會傳回適當的錯誤訊息。此函數可用於檢查輸入的參數個數是否有在正確的範圍內。
msgstr = nargoutchk (minargs, maxargs, nargs) msgstr = nargoutchk (minargs, maxargs, nargs, "string") msgstruct = nargoutchk (minargs, maxargs, nargs, "struct")
nargoutchk()
函數可用來檢查函數在呼叫時,是否有指定正確個數的傳回值,若指定的傳回值個數不正確,會傳回適當的錯誤訊息。此函數可用於檢查指定的傳回值個數是否有在正確的範圍內。
可變長度參數列(Variable-length Argument Lists)
有的時候函數的參數個數在定義函數時還沒有辦法決定,例如一個傳回最小值的函數:
a = smallest (1, 2, 3); b = smallest (1, 2, 3, 4);
所得到的 a
與 b
都是 1
,若要定義這樣的 smallest()
函數有一個辦法是將函數定義為
function val = smallest (arg1, arg2, arg3, arg4, arg5) body endfunction
然後在 body
中以 nargin
變數判斷實際傳入的參數個數進而找出最小值,但這種方式只能用於有限個數的輸入參數。
Octave 針對這種不固定參數個數的函數,提供了一個特別的方式,就是將一個特別的參數 varargin
放在最後一個參數的位置,加入這個特殊參數表示這個函數可以接受不過定的參數個數,例如上面的 smallest()
函數可以這樣定義:
function val = smallest (varargin) body endfunction
在函數的 body
中,輸入的參數可以經由 varargin
變數來取得,此變數是一個包含輸入參數的巢狀陣列(cell array,請參考巢狀陣列),所以這個函數最後可以定義成這樣:
function val = smallest (varargin) val = min ([varargin{:}]); endfunction
這樣定義的 smallest()
函數可以處理任何個數的參數,而且其程式碼非常簡單。
下面這個例子比較複雜一點,它會輸出所有的參數:
function print_arguments (varargin) for i = 1:length (varargin) printf ("Input argument %d: ", i); disp (varargin{i}); endfor endfunction
執行此函數
print_arguments (1, "two", 3);
輸出為
Input argument 1: 1 Input argument 2: two Input argument 3: 3
[reg, prop] = parseparams (params)
parseparams()
函數會將逗點分隔序列 params
分為兩部分,第一個部份是 reg
,其包含從第一個元素到第一個字串出現之前,而第二個 prop
則會包含除了 reg
之外的部分,例如:
[reg, prop] = parseparams ({1, 2, "linewidth", 10})
輸出為
reg = { [1,1] = 1 [1,2] = 2 } prop = { [1,1] = linewidth [1,2] = 10 }