4.6 M文件中变量的检测与传递
M文件中不同文件之间数据的传递是以变量为载体来实现的,数据的保存和中转则是以空间为载体来实现的。因此,M文件中变量的检测与传递是检验运算关系和运算正确与否的有力保障。
4.6.1 输入/输出变量检测指令
MATLAB中内置了相关的输入/输出变量的检测指令,如表4-8所示。
表4-8 输入/输出变量检测指令
指令名 |
功能 |
Nargin |
在函数体内获得实际的输入变量 |
Nargout |
在函数体内获得实际的输出变量 |
nargin('fun') |
获取fun指定的函数的标称输入变量数量 |
nargout('fun') |
获取fun指定的函数的标称输出变量数量 |
inputname(n) |
在函数体内给出第n个输入变量的实际调用变量名 |
说明:
(1)在函数体内使用Nargin和Nargout的目的是与程序流控制指令配合,对于不同数目的输入/输出变量,函数可以完成不同的任务。
(2)nargin、nargout和inputname本身都是函数,而不是变量,因此不能使用赋值指令对其进行处理。
4.6.2 “可变数量”输入/输出变量
MATLAB中的许多指令或函数具有输入变量可以是任意多个的特点。以MATLAB中的绘图函数plot(第6章中将会大量使用该函数)为例来说明MATLAB中的“可变数量”输入/输出变量现象。例如调用以下句式:
plot(a , b , 'PropertyName1' , 'PropertyName2' , 'PropertyValue1' , 'PropertyValue2' , …)
在上述句式中,plot函数允许使用任意多的“属性名/属性值”来精确规定绘图的规范。
在MATLAB中还有一些函数,它们也都具有“可变数量”输入/输出变量数量的性质。为了使得自主编写的程序也可以具备这条性质,MATLAB中内置了如表4-9所示的指令来实现这个功能。
表4-9 “可变数量”输入/输出变量指令
指令名 |
功能 |
varargin |
“可变数量”输入变量列表 |
varargout |
“可变数量”输出变量列表 |
说明:
(1)在编写M函数文件时,函数声明行中的“可变数量”输入/输出变量必须被放置在“正常”变量之后。
(2)在编写M函数文件时,varargin的每个元胞应当作为一个普通的输入变量来对待。
(3)varargin与varargout的工作机理类似,差别仅在于varargout承载的是输出变量和输入变量之间的配置关系。以varargin为例,该函数的工作机理如下:
① avarargin本身的数据类型为一个元胞数组。
②在M文件函数被调用时,输入变量按先后顺序依次对应分配给M函数文件的输入变量的列表中那些被明确定义的普通输入变量,然后把剩余的输入变量依次分配到varargin元胞数组的元胞中。因此,varargin元胞数组的长度取决于分配到的输入变量数量。
③所谓“可变数量”,指的是varargin的长度随着分配到的输入变量数量而改变。
例4-25:可变长度数据量使用示例。
创建M文件并命名为spiral_length.m,利用M文件编辑器在M文件中输入:
function varargout = spiral_length(d , n , varargin) % spiral画出螺旋线或螺旋条带 Nin = length(varargin) + 1; if nargout > 1 erroe('Too many output arguments!!!') end j = sqrt(-1); phi = 0 : pi / 20 : n * 2 * pi; amp = 0 : d / 40 : n * d; spir = amp .* exp(j * phi); if nargout == 0 switch Nin case 1 plot(spir , 'b') case 2 d1 = varargin{1}; amp1 = (0 : d / 40 : n * d) + d1; spir1 = amp1 .* exp(j * phi); plot(spir , 'b'); hold on; plot(spir1 , 'b'); hold off otherwise d1 = varargin{1}; amp1 = (0 : d / 40 : n * d) + d1; spir1 = amp1 .* exp(j * phi); plot(spir , varargin{2 : end}); hold on; plot(spir1 , varargin{2 : end}); end axis('square') else phi0 = 0 : pi / 1000 : n * 2 * pi; amp0 = 0 : d / 2000 : n * d; spir0 = amp0 .* exp(j * phi0); varargout{1} = sum(abs(diff(spir0))); if Nin > 1 d1 = varargin{1}; amp1 = (0 : d / 2000 : n * d) + d1; spir1 = amp1 .* exp(j * phi); varargout{2} = sum(abs(diff(spir1))); end end
在命令行窗口中输入:
subplot(1,3,1),spiral_length(2,2,1) subplot(1,3,2),spiral_length(2,2,1, 'Marker', 'o') subplot(1,3,3),spiral_length(2,2,1, 'r-- ' , 'LineWidth',2)
输出结果如图4-8所示。
图4-8 输出结果
4.6.3 跨空间变量传递和赋值
1.跨空间变量传递
在MATLAB中,不同工作区之间的数据传递是通过变量来实现的,主要形式有两种:函数的输入/输出变量和全局变量。本节将对除此之外的第3种数据传递渠道——跨空间计算表达式的值进行介绍。其具体的调用格式如下。
● evalin('工作区','expression'):该指令的功能为跨空间计算字符串表达式的值。
说明:
(1)“工作区”的可取值有两个,分别是“base”和“caller”。
(2)工作机理为:①当“工作区”为“base”,表达式计算eval("expression")时,将从基本工作区获得变量值;②当“工作区”为“caller”,表达式计算eval("expression")时,将从主调函数基本工作区获得变量值。主调函数是相对于被调函数而言的,被调函数是指evalin所在的函数。
● evalin('工作区','expression1','expression2'):该指令的功能为跨空间计算替代字符串表达式的值。
说明:
(1)“工作区”的可取值有两个,分别是“base”和“caller”。
(2)工作机理为先从所在函数空间获取变量值,用eval("expression1")计算原字符串表达式,如果该计算失败,则从“工作区”指定的基本工作区或主调函数工作区获得变量值,再通过eval("expression2")计算替代字符串表达式的值。
例4-26:跨空间变量传递示例。
创建M文件并命名为ex4_26.m,利用M文件编辑器在M文件中输入:
clear all;close all; n = 6; % n = 6 , 作出的图片为6瓣的花 j = sqrt(-1); phi = 0 : pi / (20 * n) : 2 * pi; amp = 0; for i = 1 : n amp = [amp 1 / 20 : 1 / 20 : 1 19 / 20 : -1 / 20 : 0]; end string = {'base' , 'caller' , 'self'}; % 在本例中,当字符串为"base"时,调用基本工作区 % 当字符串为"caller"时,调用函数空间 % 当字符串为"self"时,调用子函数空间 for i = 1 : 3 y = Flower(5 , string{i}); % n = 5,作出的图片为5瓣的花 subplot(1 , 3 , i) plot(y , 'r' , 'LineWidth' , 4) axis('square') end
创建M文件并命名为Flower.m,利用M文件编辑器在M文件中输入:
function y1 = Flower (n,s) j = sqrt(-1); phi = 0 : pi / (20 * n) : 2 * pi; amp = 0; for i = 1 : n amp = [amp 1 / 20 : 1 / 20 : 1 19 / 20 : -1 / 20 : 0]; end y1 = subflower (4,s); % n=4,作出的图片为4瓣的花 % -------------- subfunction ----------------- function y2 = subflower(n, s) j = sqrt(-1); phi = 0 : pi / (20 * n) : 2 * pi; amp = 0; for i = 1 : n amp = [amp 1 / 20 : 1 / 20 : 1 19 / 20 : -1 / 20 : 0]; end func= 'amp .* exp(j * phi)'; switch s case { 'base' , 'caller'} y2=evalin (s, func) ; case 'self' y2=eval (func) ; end
运行文件,输出图像如图4-9所示。
图4-9 输出图像
2.跨空间变量赋值
实现不同工作区之间变量传递的第4种方式是跨空间变量赋值,其具体的调用格式如下。
● assignin('工作区','VN',x):该指令的功能是为跨空间变量VN赋值,把当前工作区中的变量x的值赋给指定的“工作区”中的指定变量VN。assignin的使用机理与跨空间变量传递的机理相同,因此此处不再举例说明,只举例说明使用assignin指令的注意事项。
例4-27:assignin运作机理示例。
在命令行窗口中输入:
assignin('base' , 'Num' , 0) Num
输出结果:
Num = 0
在命令行窗口中输入:
Array = 1 : 10; assignin('base' , 'Array(4 : 7)' , Num)
输出结果:
错误使用 assignin ASSIGNIN 中的变量名称 "Array(4 : 7)" 无效。
在命令行窗口中输入:
evalin('base' , 'Array(4 : 7) = Num')
输出结果:
Array = 1 2 3 0 0 0 0 8 9 10