MATLAB程序设计语言(2.1)---变量的作用域
公众号:理念世界的影子
文不可无观点,观点不可无论据。
转载请注明出处
MATLAB功能强大,编程方便,是国际广泛使用的计算软件。目前已有很多书籍介绍其在工程上的应用,但很少有从程序设计语言的角度写的书或文章。
MATLAB准备写一个系列,50~100篇左右。内容是笔者的心得,追求市面的书上没有的,都是有小程序作为案例的。上一篇阅读量极少,有没有可能是内容较多,程序较多,让人烦躁?补充这篇算是补救吧,采用短文章风格。
MATLAB将变量存储在工作空间内(workspace),基工作空间(base workspace)保存MATLAB命令窗口或脚本中的变量。函数不使用基工作空间,每个函数有自己单独的工作空间,以实现数据的隔离保护。大多数情况下,MATLAB函数中的变量只能在函数中使用,而不能在其它函数和基工作空间使用,数据交互采用函数参数传递形式。
全局变量
global:global将变量申明为全局变量,注意的是,1)变量的申明必须在赋值前;2)全局变量在被引用前,需再次使用global声明。
persistent:persistent是一种特殊的全局变量,它仅对本很函数可见。运行下述函数多次,可发现其返回值每次递减。本命令类似于C语言下的static命令,值得注意的是,其初始化方法与C语言不同(static a=3;),而且此变量可以被clear functions命令(functions指具体的函数名)清除,除非在函数内增加mlock命令。
1 functionvariablescope
2 persistenta;
3 if(isempty(a)) a=3;end
4 a=a-1;
5 disp(a);
引用父(或基)工作空间
1 v = evalin('base', 'var');
其中evalin的第一个参数可以为’base’或’caller’,分别指基和父工作空间。
对基工作空间或父工作空间幅值
1 assignin('base', 'a', -1);
也可以使用:
1 evalin('base', 'a=-1;');
外部文件交换
采用外部文件交换可以跨越所有空间,在MATLAB内,save函数用于将本空间变量保存到文件中,load用于将变量导入本函数。
闭包
嵌套函数和匿名函数提供了一种称为闭包的能力。如下ode45的第一个参数为函数名,一般传入时间和自变量x,但有时需要传入更多的参数,这时可以使用λ函数(匿名函数)。
1 ode45(@(t, x, a) fun(t, x, a), tspan, x0, a)
值得注意的是,对于下述程序
1 a=3; b=@() a; b(), a=4; b()
其返回值均为3,这是因为b函数本身包括了被声明当时所处的环境,当外界环境改变时,它仍保留了当时的环境,这种保留当时环境的特性被称为闭包,它带来了一系列编程特性,将在讲函数型数据时详述。
自省
MATLAB变量大部分表现与C语言相同,但其实现机制完全不同。C语言运行时,对变量的引用只表现为地址的指针的引用,其源程序中的名称已完全消失。在MATLAB中,当对变量赋值时,变量存在一个标签,从而也多出了更多的自省的机制。
直接运行whos命令,可以打印所有的变量。如下命令将工作空间内所有变量压缩到一个结构体内:
如下命令查看某个变量是否存在:exist('want_known', 'var');
如下命令查看函数中输入或输出参数有几个:nargin, nargout
如下命令传入函数的可变输入或输出参数:vargin, vargout
如下命令查看父函数名称:mfilename, dbstack
如下命令查看函数参数传入时的真实名称:inputname, dbstack
例如vargin, vargout可以这样使用
matlab不支持a=b=c=d=e=f=g=1的赋值,一个一个赋值太麻烦,这时可以采用逗号分隔符
或写为
deal函数代码如下
deal.m, MATLAB自带程序, edit deal即可看到
1 functionvarargout = deal(varargin)
2 ifnargin==1,
3 varargout = varargin(ones(1,nargout));
4 else
5 ifnargout ~= nargin
6 error('MATLAB:deal:narginNargoutMismatch',...
7 'The number of outputs should match the number of inputs.')
8 end
9 varargout = varargin;
10 end
又如下述例子利用了跨域赋值和自省功能,可以在不返回值的情况下交换两输入参数。
1 functionexchangevar (a, b)
2 % 交换a、b变量的值
3 assignin('caller', inputname(1), b);
4 assignin('caller', inputname(2), a);
尽管MATLAB提供了更为丰富和方便的作用域控制功能,但编程序时并不建议使用。它使得函数逻辑复杂,程序更容易出错,调试更为困难,而且对于同一程序的同一形参,多次运行可能出现不同的返回值。在程序设计时常会追求一种引用透明性,即对同一程序同一形参的多次使用返回值均相同。这种理念引申出了一种不同于面向过程、面向对象的编程范式,称之为函数式编程,也将在后续介绍。函数式编程大家不一定要用,但学习后,对提高编程能力有所益处。
往期文章:
MATLAB《MATLAB程序设计语言(2)---help的see also与六度空间理论》
微信扫一扫
关注“理念世界的影子”
版权声明:
本文是"洞穴之外"作者原创文章,欢迎转载,须署名并注明来自“理念世界的影子”公众号。