循环控制结构

Mathematica 程序的执行涉及到一系列表达式的计算. 在简单程序中,由;分开的表达式将逐个计算,但在一些循环中,某些表达式可能被计算多次.

Do[expr,{i,imax}]i,增量为 ,重复计算 expr
Do[expr,{i,imin,imax,di}]i,增量为 di,重复计算 expr
Do[expr,{i,list}]i 取值于 list,计算 expr
Do[expr,{n}]计算 expr n

简单循环结构.

计算 Print[i^2].
,增量为 ,对 进行赋值.
In[2]:=
Click for copyable input
Out[2]=

Do 中定义的循环方式和函数 TableSum 中的相同. 与这些函数类似,可以使用 Do 循环嵌套.

循环,对每一个 循环.

有时需要进行某一个运算多次,但还不希望改变迭代变量的值. 可以用如 Table 和其它迭代函数中使用的类似方法在 Do 循环中实现这一要求.

重复赋值 三次.
In[4]:=
Click for copyable input
Out[4]=
可以在 Do 循环中使用过程.
Nest[f,expr,n]f 作用于 expr n
FixedPoint[f,expr]expr 开始反复使用 f 直到结果不再改变
NestWhile[f,expr,test]expr 开始反复使用 f 直到 test 的值不为 True

重复使用函数.

Do 对迭代变量的不同值反复计算一个表达式,使用户能进行重复运算. 但用 "函数的重复调用" 节介绍的函数编程结构能编写出更有效的程序. Nest[f, x, n] 等可以对一个表达式反复运用函数.

这里函数 迭代三次.
In[6]:=
Click for copyable input
Out[6]=
对纯函数迭代,也能得出前面使用 Do 的例子中的结果.
In[7]:=
Click for copyable input
Out[7]=

Nest 可以重复运用函数若干次,用时要反复使用函数直到结果不再改变为止,这可以用 FixedPoint[f, x] 来实现.

FixedPoint 重复使用函数直到结果不再改变为止.
In[8]:=
Click for copyable input
Out[8]=

FixedPoint 可用来模仿 Mathematica 的计算过程或 等函数运算. FixedPoint 一直重复执行到相继两个结果不再变化为止. 而 NestWhile 一直重复执行到任一个函数不再产生 True 为止.

Catch[expr]计算 expr 直到遇见 Throw[value],返回值为 value
Catch[expr,form]计算 expr 直到 Throw[value, tag] 出现,其中 formtag 匹配
Catch[expr,form,f]返回值为 而不是 value

计算的非局部控制.

遇到 Throw 时停止计算,Catch 的返回值是 的当前值.
In[9]:=
Click for copyable input
Out[9]=

ThrowCatch 提供了在 Mathematica 中计算控制的又一方式. 当遇到 Throw 后计算过程停止,Mathematica 就返回到最近的一个 Catch.

Scan 使用 Print 函数在每个元素上,最后返回值为 Null.
遇到 ThrowScan 的计算结束,所含的 Catch 返回值是 Throw 变量的值.
In[11]:=
Click for copyable input
Out[11]=
Map 也可以得到同样的结果,当计算过程不是遇到 Throw 时结束,Map 的返回值是一个集合.
In[12]:=
Click for copyable input
Out[12]=

ThrowCatch 可以改变函数的编程结构,使得计算过程到一定条件出现时结束. 注意,用 Throw 结束的计算的结果可能和计算全部完成得到的结果不一样.

反复使用一个函数得到的集合.
In[13]:=
Click for copyable input
Out[13]=
由于没有遇到 Throw,所有结果与前面相同.
In[14]:=
Click for copyable input
Out[14]=
现在 NestList 的计算被改变,显示的是 Throw 变量的返回值.
In[15]:=
Click for copyable input
Out[15]=

ThrowCatch 完全以一种全局的方式运行,不管哪儿或怎样出现 Throw,它都使计算停止,回到所包含的 Catch.

Throw 停止 计算,使 Catch 的返回值为 没有任何信息留下.
In[16]:=
Click for copyable input
Out[16]=
这里定义一个当其自变量的值大于10时就产生 Throw 函数.
In[17]:=
Click for copyable input
此处没有出现 Throw.
In[18]:=
Click for copyable input
Out[18]=
但这里在 的计算过程中产生的 Throw 返回到了所包含的 Catch.
In[19]:=
Click for copyable input
Out[19]=

在小的程序中,用 Throw[value]Catch[expr] 的最简单形式是合适的. 但在包含许多块的程序中,最好用Throw[value, tag]Catch[expr, form]. 通过保持表达式 tagform 在程序的某一块中,就可以保证 ThrowCatch 也在这一块中运行.

这里内部的 Catch 用到 Throw.
In[20]:=
Click for copyable input
Out[20]=
但这里仅外面的 Catch 用到了 Throw.
In[21]:=
Click for copyable input
Out[21]=
可以用模式去指定哪个 Catch 应该捕获标志.
In[22]:=
Click for copyable input
Out[22]=
这里保证标志 是局部的.
In[23]:=
Click for copyable input
Out[23]=

应该认识到当 Throw 是常数时没有必要用标志; 一般来说它可以是任何表达式.

这里内部的 Catch 用标志小于4的所有 throw,继续进行 Do 循环. 档标志达到4时,就用外面的 Catch.
In[24]:=
Click for copyable input
Out[24]=

使用 Catch[expr, form]Throw[value, tag] 时,Catch 的返回值是 Throw 中的 value. 使用Catch[expr, form, f] 时,Catch 的返回值是 .

作用于 Throw 中的 value 和 tag 上.
In[25]:=
Click for copyable input
Out[25]=
Throw 时,就不使用 .
In[26]:=
Click for copyable input
Out[26]=
While[test,body]test 值为 True 是反复计算 body
For[start,test,incr,body]计算 start,接下来反复计算 bodyincr,直到 test 的值为 False 时停止

一般的循环结构.

DoNestFixedPoint 等函数在 Mathematica 中用来进行循环,而 ThrowCatch 可以用来修改这种结构. 有时需要建立没有结构的循环,用 WhileFor 就能方便地做到这一点,它们反复进行运算,直到某条件不成立时停止.

While 循环一直进行到条件不成立时结束.

MathematicaWhileFor 函数与C语言中的 控制结构类似. 但也有些重要的区别. 例如, Mathematica For 循环和C语言中的逗号和分号的位置正好相反.

这是一个常用的 For 循环. 使 增加.
这是一个更复杂的 For 循环. 当条件 不成立时结束循环.

Mathematica 中的 WhileFor 循环中,总是先测试条件是否成立,然后再进行循环的计算. 当循环测试结果不为True 时,WhileFor 循环结束. 所以,循环体仅在测试结果为 True 时计算.

循环条件不成立,故循环体没有进行计算.
In[30]:=
Click for copyable input

While 循环、For 循环以及 Mathematica 的过程中,Mathematica 表达式按确定的顺序进行计算. 可以将这种顺序看作 Mathematica 程序执行中的控制流.

大部分情况下应该是 Mathematica 程序的控制流尽可能的简单. 控制流对于执行过程中产生的值依赖越多,理解该程序运行结构就越困难.

功能编程结构涉及非常简单的控制流. 由于 WhileFor 循环中的控制流依赖于测试条件的值,它们是较复杂的. 即使在这样的循环中,控制流一般不依赖于循环体中表达式的值.

在一些情况中,Mathematica 程序中的控制流受一个过程执行中所产生结果的影响,或受循环体所产生结果的影响. 处理这种情况的一个方法是用 ThrowCatch. Mathematica 也提供了修改控制流的其它函数,这与C语言中的情况类似.

Break[]退出最接近的内循环
Continue[]进行本循环的下一步
Return[expr]返回函数中的值 expr
Goto[name]转入当前过程中的 Label[name] 元素
Throw[value]value 作为最接近的 Catch 的返回值 (非局部返回)

流程控制函数.

大于 时, Break[] 导致循环结束.
时,Continue[] 使循环跳过 继续执行.

Return[expr] 使程序退出一个函数,得到一个返回值. 可以将 Throw 看作一个非局部返回,因为它退出了整个嵌套函数列,这种特性在处理一些错误条件时非常方便.

这里提供了一个使用 Return 的例子. 在以下这个特例中,如果不使用 Return,过程也一样正常运行.
In[33]:=
Click for copyable input
当变量的值大于5时,使用第一个 Return.
In[34]:=
Click for copyable input
Out[34]=
当变量值为负时,这一函数给出 错误提示.
In[35]:=
Click for copyable input
这里没有 Throw 错误.
In[36]:=
Click for copyable input
Out[36]=
这里产生了 ThrowCatch 的返回值是 .
In[37]:=
Click for copyable input
Out[37]=

Continue[]Break[] 函数等可以使 Mathematica 程序转到循环开始或结束循环. 有时,还需要将程序转到过程的某一处. 如果在过程中给出作为元素的 Label,就可以使用 Goto 语句转到该处去.

循环进行到 超过 时结束.

只有在 Label 作为元素出现的同一 Mathematica 过程中,才能使用对这个特定 Mathematica 过程使用 Goto. 一般来说,使用 Goto 语句可以简化程序结构,但程序的运行过程却复杂了一些.

New to Mathematica? Find your learning path »
Have a question? Ask support »