Matlab的变量作用域分为工作区作用域和函数作用域,两个作用域是完全相互独立的,即workspace(以下简称ws)定义的变量与function(以下简称f)中定义的变量毫无瓜葛。
但是两个作用域的变量之间可以通过某些函数相互联系,以下我们会介绍一些函数,其中几个平时可能都不多见。
· assignin
· evalin
· persistent
· global
严格地说,我们应该把ws中的变量,以及f中的变量都称之为局部变量。但是,从编程的角度讲,函数中定义的仅作用在函数作用域内的变量,我们才称之为局部变量。此外,由于ws的即视,也让我们更愿意将ws称之为全局的区域。全局变量的关键字global我们都已经很熟悉了,此处也不多赘述,仅列出两大特点
· 需要用clear all命令进行清楚,否则一直存在于内存中
· 在ws中调用全局变量,也需要加global关键字
三、 工作空间与函数空间的非全局变量交互
在f中,我们无法直接调用ws中已经存在的变量a,我们需要凭借evalin函数进行读取
a = evalin('ws','a');
通过上述语句,可以获取ws中的a。我们可以轻易发现,该函数的第二个输入参数,是变量的名称,但是第一个参数,如果我不提前对workspace进行简写得到ws,恐怕各位难以想到。于是你知道了,第一个参数是来确定被调取变量的作用域的。后来,你开始猜测——第一个参数,除了ws还有什么?难道是f?且看后文分析。
我们先定义个两个函数testfun,其内部还有个子函数subfcn,我们知道当subfcn不在testfcn的end作用域内时,变量是互不相通的。我们可以用evalin函数。第一个参数改成'caller',这就是你们想问的,除了'ws',其他参数的是什么。
function testfcn
b = 1;
subfcn;
end
function subfcn
b = evalin('caller','b');
disp(b+1);
end
通过上述语句,可以获取ws中的a。我们可以轻易发现,该函数的第二个输入参数,是变量的名称,但是第一个参数,如果我不提前对workspace进行简写得到ws,恐怕各位难以想到。于是你知道了,第一个参数是来确定被调取变量的作用域的。后来,你开始猜测——第一个参数,除了ws还有什么?难道是f?且看后文分析。
对于将f中的变量b,存放到ws中,即在函数运行结束后b存在于ws,我们需要凭借assignin函数进行保存
assignin('ws','c',c);
当你知道了'ws'之类的参数还有'caller'的时候,你肯定知道了我接下来要讲什么。如何把子函数内的参数放到主函数里。
function testfcn
subfcn;
disp(d);
end
function subfcn
d = 1;
assignin('caller','d',d);
end
现在你应该知道了,'caller'顾名思义,就是调用这个这个函数的函数或者....
当然是或者普通脚本了,我们试试即可!
function testfcn
k = 5;
assignin('caller','k',k);
end
-----------------------------------------------mycaller.m
clear;
clc;
testfcn;
disp(k);
结果肯定是输出了5。此外,workspace出现变化了:
理所应当吧?必须理所应当!!!因为普通m文件绑定的就是ws,因此,当普通m文件调用testfcn时,assignin的第一个参数用caller和ws是一样的。
persistent关键字声明的变量是静态变量,什么是静态变量呢?学过c的朋友应该知道,它的作用域仅在定义它的end内,但是这种变量不会因为函数调用结束而消失,会一直存在内存中。同时,静态变量仅初始化一次。简单例子如下:
function testfcn
persistent a
disp(isempty(a));
end
这时候testfcn是会返回1的,我们声明了a但是未进行赋值。我们改进函数更加直观地体现a的作用域。
function testfcn
testfcn2;
disp(isempty(a));
end
function testfcn2
persistent a
if isempty(a)
a = 1;
disp(a);
return;
end
a = a+l;
disp(a);
end
可见主函数是无法获取a的。接下来去除错误代码段,我们看一下,静态变量a随着子函数的调用,其值的变化
function testfcn
testfcn2;
testfcn2;
testfcn2;
testfcn2;
testfcn2;
end
function testfcn2
persistent a
if isempty(a)
a = 1;
disp(a);
return;
end
a = a+1;
disp(a);
end
可见a确实随着testfcn2子函数的调用而增加。值得一提的是,静态变量的清楚与全局变量一样,都需要clear all。
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删