深入理解MATLAB变量作用域

一、概述

       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的作用

       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。



免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删

QR Code
微信扫一扫,欢迎咨询~

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 155-2731-8020
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

手机不正确

公司不为空