与许多其他计算机语言不同,Octave允许您定义返回多个值的函数。定义返回多个值的函数的语法如下:
function [ret-list] = name (arg-list) body endfunction
其中name、arg-list和body的含义与之前相同,而ret-list是一个以逗号分隔的变量名列表,用于存放函数返回的值。返回值列表必须至少包含一个元素。如果ret-list只有一个元素,则这种形式的function语句与上一节中描述的形式等价。
下面是一个函数示例,它返回两个值:向量的最大值以及该值在向量中首次出现的索引。
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
在这个特定例子中,这两个值可以作为单个数组的元素返回,但这并不总是可行或方便的。需要返回的值可能不具有兼容的维度,而且通常希望为各个返回值赋予不同的名称。
可以使用nthargout函数来只获取部分返回值,或一次性在元胞数组中获取多个返回值。
参见元胞数组对象。
arg = nthargout (n, fcn, …) ¶arg = nthargout (n, ntot, fcn, …) ¶返回由函数句柄或字符串fcn所指定函数的第n个输出参数。
任何额外的参数都会直接传递给fcn。可以通过ntot传入调用fcn时使用的参数总数;默认情况下ntot等于n。输入参数n也可以是一个输出索引的向量,此时输出将是一个包含所请求输出参数的元胞数组。
nthargout的预期用途是避免使用中间变量。例如,在查找矩阵最大元素的索引时,以下两个nthargout的组合使用
m = magic (5);
cell2mat (nthargout ([1, 2], @ind2sub, size (m),
nthargout (2, @max, m(:))))
⇒ 5 3
完全等价于以下代码:
m = magic (5); [~, idx] = max (M(:)); [i, j] = ind2sub (size (m), idx); [i, j] ⇒ 5 3
如下代码所示,将所有输出参数收集到单个元胞数组中也很有帮助:
USV = nthargout ([1:3], @svd, hilb (5));
编程提示:nthargout函数的等效功能通常可以通过在代码中使用字符‘~’来忽略输出来实现。此功能由Octave解释器提供,且比使用本函数更高效。
等效代码:
idx = nthargout (2, @max, rand (100, 1)); ≡ [~, idx] = max (rand (100, 1));
除了在每次调用函数时设置nargin之外,Octave还会自动将nargout初始化为期望返回的值的数量。这允许您编写根据函数用户请求的返回值数量而表现不同的函数。对内置变量ans的隐式赋值不计入输出参数的计数,因此nargout的值可能为零。
svd和hist函数就是根据nargout的值表现不同的内置函数示例。例如,hist在没有输出变量的情况下调用时会绘制直方图,但如果调用时指定了输出,则它会返回频率计数和/或组边界,而不会创建图形。
可以编写只设置部分返回值的函数。例如,调用函数
function [x, y, z] = f () x = 1; z = 2; endfunction
如下所示:
[a, b, c] = f ()
会得到:
a = 1 b = [](0x0) c = 2
同时会显示一条警告。
n = nargout () ¶n = nargout (fcn) ¶报告函数的输出参数数量。
在函数内部调用时,返回调用者期望接收的值的个数。在顶层调用时,不带参数的nargout未定义,会产生错误。
如果使用可选参数fcn(函数名或句柄)调用,则返回该函数可以产生的已声明的输出值个数。
如果最后一个输出参数是varargout,则返回值为负数。
例如,
f ()
将使nargout在函数f内部返回0,而
[s, t] = f ()
将使nargout在函数f内部返回2。
在第二种用法中,
nargout (@histc) # 或使用字符串输入 nargout ("histc")
将返回2,因为histc有两个输出,而
nargout (@imread)
将返回-2,因为imread有两个输出,且第二个是varargout。
编程提示:nargout不适用于内置函数,对于所有匿名函数返回-1。
版权所有 © 2024-2026 Octave中文网
ICP备案/许可证号:黑ICP备2024030411号-2