嵌套函数,即nested function,就是嵌套在函数体内部的函数。嵌套函数可以出现在一个函数体内部的任何位置,开始以function声明,结束的时候加上end。需要说明的是包含有嵌套函数的函数,无论它是主函数、子函数、嵌套函数,都应该在末尾的地方加上end。下面的代码是一个简单的嵌套函数的例子
例1
例2
function x=A(p1,p2)... function y1=B1(p3) ... function z1=C1(p4) ... end ... end... function y2=B2(p5) ... function z2=C2(p6)_ ... function w=D(p7) ... end end endend 该函数A(p1,p2)内部有两个嵌套函数,分别B1(p3)和B2(p5),而B1(p3)和B2(p5)分别是二重和三重嵌套函数。 嵌套函数的变量作用域例1
function r=NestedFunctionVarScopeDemo(a)b=a+1; function Nested1 c=b+1; function Nested11 d=c+a; end Nested11; endNested1r=d;end运行上面的代码,譬如
r=NestedFunctionVarScopeDemo(1)r = 4 上述代码有一个二重嵌套函数Nested1,它内部还包含一个嵌套函数Nested11,整个函数的执行过程如下:传入变量a=1,计算b的值,b=2;遇到Nested1的函数定义,往下是调用Nested1的语句,进入Nested1之后先计算c的值,即c等于b+1=3。从这里可以看到,在嵌套函数体内,可以访问主函数之内的变量。“c=b+1;”这条语句之后是定义Nested11的函数语句,定义Nested11结束后,是调用Nested11的函数语句。从Nested11的定义来看,这个函数非常简单,仅仅做的是计算d=c+a;从这里可以看出在第二重嵌套函数里,分别访问了Nested1里的变量c和主函数里的变量a。主函数最后一句是从外部访问了第二重嵌套函数里的变量d,并将d赋给r,以此作为主函数的返回值。 从上面这个嵌套函数的示例可以看出,主函数和嵌套在其内的函数,它们各自的变量是可以互相访问的。但是必须要注意的是,嵌套函数访问主函数的变量,可以在函数定义里直接拿过来用,而主函数访问嵌套在其内的函数里的变量则必须要经过调用之后才能用。譬如上例主函数访问Nested11里的d,是经过在主函数里调用Nested1,而在Nested1里又调用Nested11后才成功的,否则是不行的。例2
function r=NestedFunctionVarScopeDemo2(a)b=a+1; function Nested1 c=b+1; c1=10; function Nested11 d=c+a; end endNested1e=c1r=d;end运行得到如下结果
r=NestedFunctionVarScopeDemo2(1)e = 10未定义函数或变量 'd'。出错 NestedFunctionVarScopeDemo2 (line 12)r=d; 在调用NestedFunctionVarScopeDemo2时候发生了错误。从提示来看,是没有定义变量“d”。这是因为调用Nested1后执行了Nested1里的语句,但是Nested1中只是定义了Nested11,而并没有调用它的语句。因此,外界不能访问d。这就是为什么e=c1;可以成功而r=d;报错的原因了。上面讨论了嵌套函数和主函数之间变量互相访问的情况(包括主函数也是嵌套函数的情况)。那么不同的嵌套函数之间呢?如下例例3
function r=NestedFunctionVarScopeDemo3(a)b=a+1; function Nested1 c=b+1; c1=10; Nested2; c2=d^2; end function Nested2 d=2*b; endNested1r=c2end 该函数里面包含两个嵌套函数,都是单重的,一个是Nested1,一个是Nested2。本例是想验证,是否直接从Nested1中通过调用Nested2来访问其中的变量。经过运行得到下面的结果: >> r=NestedFunctionVarScopeDemo3(1)未定义函数或变量 'd'。出错 NestedFunctionVarScopeDemo3/Nested1 (line 7) c2=d^2;出错 NestedFunctionVarScopeDemo3 (line 12)Nested1 从错误提示来看,出错原因是访问变量“d”不成功,“d”未定义,所以彼此没有嵌套关系的嵌套函数是不能简单得共享变量的,如果非要共享,只能通过他们所在的主函数来进行。 嵌套函数彼此调用关系 主函数和嵌套函数之间 这里的主函数包括最上层的主函数,即不嵌套在任何函数里的函数以及本身是嵌套函数,但同时内部还嵌套有其他函数的函数。因为这些函数相对嵌套在内的函数来说也是主函数。这样的情形下,调用关系遵循下面的原则:主函数可以调用嵌套在其中的第一重嵌套函数而不能调用第二重或者更深重的嵌套函数;无论第几重嵌套函数,都可以调用主函数或者主函数的主函数等等
如下例
从结果来看,调用Nested1成功,而调用Nested11没有成功。这验证了主函数可以调用嵌套在其中的第一重嵌套函数,而不能调用第二重或者更深重的嵌套函数
下例为嵌套函数调用主函数的例子
运行上述代码,得到下面结果
>> NestedFunctionCallDemo2(2)flag=2flag=1flag=3当flag=2时,执行的是NestedFun1,而在NestedFun1中调用了主函数,这时候flag=1;因此此时显示“flag=1”,接下来在NestedFun1中对NestedFun2进行了调用。而NestedFun2对最外层的主函数来说是一个二重嵌套函数,同样它也调用了NestedFunctionCallDemo2,只不过flag=3,因此显示“flag=3”。从上例可以看出,嵌套函数对主函数的调用是可以的。
不同的嵌套函数之间 这里讨论的不用嵌套函数之间指的是嵌套深度相同或者不同,彼此之间没有嵌套与被嵌套关系的不同的嵌套函数。譬如位于第一层的不同嵌套函数之间,以及位于第二层的不同嵌套函数之间,等等。如下例嵌套函数调用示例1
function NestedFunctionCallDemo3Nested1(5) function Nested1(x) disp(['Nested1 执行,输入:',num2str(x)]); Nested2(6) function Nested11(xx) disp(['Nested11 执行,输入:',num2str(xx)]); end end function Nested2(y) disp(['Nested2 执行,输入:',num2str(yy)]); function Nested22(yy) disp(['Nested22 执行,输入:',num2str(yy)]); end endend运行结果如下:
Nested1 执行,输入:5Nested2 执行,输入:6 从上面结果来看,Nested1执行后成功调用Nested2这说明第一层的嵌套函数之间是可以互相调用的。嵌套函数调用示例2
function NestedFunctionCallDemo4Nested1(5) function Nested1(x) disp(['Nested1 执行,输入:',num2str(x)]) Nested11(6) function Nested11(xx) disp(['Nested11 执行,输入:',num2str(xx)]) Nested2(pi) Nested22(10); end end function Nested2(y) disp(['Nested2 执行,输入:',num2str(y)]) Nested22(pi*pi) function Nested22(yy) disp(['Nested22 执行,输入:',num2str(yy)]) end endend运行代码,得到
>> NestedFunctionCallDemo4Nested1 执行,输入:5Nested11 执行,输入:6Nested2 执行,输入:3.1416Nested22 执行,输入:9.8696未定义函数或变量 'Nested22'。出错 NestedFunctionCallDemo4/Nested1/Nested11(line 9) Nested22(10);出错 NestedFunctionCallDemo4/Nested1 (line 5) Nested11(6)出错 NestedFunctionCallDemo4 (line 2)Nested1(5) 从上面的执行情况可以看出函数Nested11成功被调用,而且Nested11再调用Nested2时也成功了,通过Nested2,间接调用了Nested22,但是从Nested11中直接调用Nested22却没有成功。说明第二重调用可以调用不包含它的第一重嵌套函数。嵌套函数调用3
function NestedFunctionCallDemo5Nested1(5) function Nested1(x) disp(['Nested1 执行,输入:',num2str(x)]) Nested11(6) function Nested11(xx) disp(['Nested11 执行,输入:',num2str(xx)]) Nested111(pi) function Nested111(xxx) disp(['Nested111 执行,输入:',num2str(xxx)]); Nested2(exp(1)) Nested22(100) end end end function Nested2(y) disp(['Nested2 执行,输入:',num2str(y)]) Nested22(pi*pi) function Nested22(yy) disp(['Nested22 执行,输入:',num2str(yy)]) end endend运行代码结果为:
Nested1 执行,输入:5Nested11 执行,输入:6Nested111 执行,输入:3.1416Nested2 执行,输入:2.7183Nested22 执行,输入:9.8696未定义函数或变量 'Nested22'。出错NestedFunctionCallDemo5/Nested1/Nested11/Nested111(line 12) Nested22(100)出错 NestedFunctionCallDemo5/Nested1/Nested11(line 8) Nested111(pi)出错 NestedFunctionCallDemo5/Nested1 (line 5) Nested11(6)出错 NestedFunctionCallDemo5 (line 2)Nested1(5) 从上面的执行情况可以看出,函数Nested1执行后,函数Nested11成功被调用,而且Nested11在调用Nested111,Nested111在调用Nested2时也成功了;通过Nested2,Nested111间接调用了Nested22,但是从Nested111直接调用Nested22却没有成功。这说明第三重嵌套函数,不可以调用不包含它的第二重嵌套函数。 嵌套函数调用关系总结 为了方便理解。可以将上述调用情况进行类比具体如下将主函数看成“父亲”,嵌套函数依据嵌套深度可以看成“儿子”,“孙子”,“重孙子”,等等。
父亲可以求助儿子,儿子可以求助父亲。即父子可以互相求助。一个人不能求助孙子,重孙等后代,但是可以求助自己的祖宗(wxdlm、曾wxdlm等等)。一个人可以求助自己亲兄弟,或者隐形的牛排、mldwd但不能求助害怕的未来