2.5.9 循环控制结构Mathematica 程序的执行涉及到一系列表达式的计算,在简单程序中, 由;分开的表达式将逐个计算,但在一些循环中,某些表达式可能 被计算多次. 简单循环结构 i 从 1 到 4 计算 Print[i^2]
k 从 2 到 6,增量为 2,对 t 进行赋值
Out[2]= |  |
Do 中定义的循环方式和函数 Table 和 Sum 中的相同,与这些函数类似, 可以使用 Do 循环嵌套. i 从 1 到 4 循环,对每一个 i,j 从 1 到 i-1 循环
有时需要进行某一个运算多次,但还不希望改变迭代变量的值, 可以用如 Table 和其它迭代函数中使用的类似方法在 Do 循环中实现 这一要求. 重复赋值 t = 1/(1+t) 3 次
Out[4]= |  |
可以在 Do 循环中使用过程
重复使用函数 Do 对迭代变量的不同值反复计算一个表达式,使用户能进行重复运算. 但用 2.2.2 节中介绍的函数编程结构能编写出更有效的程序. Nest[f,x,n] . 这里函数 f 迭代 3 次
Out[6]= |  |
对纯函数迭代,也能得出前面用 Do 函数一样的结果
Out[7]= |  |
Nest 可以重复运用函数若干次,用时要反复使用函数直到结果不再改变为止, 这可以用 FixedPoint[f, x] 来实现. FixedPoint 重复使用函数直到结果不再改变为止
Out[8]= |  |
FixedPoint 可用来模仿 Mathematica 的计算过程或 等函数运算. FixedPoint 一直重复执行到相继两个结果不再变化为止. 而 NestWhile 一直重复执行到任一个函数不再产生 True 为止. 计算的非局部控制 遇到 Throw 时停止计算,Catch 的返回值是 i 的当前值
Out[9]= |  |
Throw 和 Catch 提供了计算控制的又一方式,当遇到 Throw 后计算过程停止, Mathematica 就返回到最近的一个 Catch. Scan 使用 Print 函数在每个元素上,最后返回值为 Null
遇到 Throw 后 Scan 的计算结束,所含的 Catch 返回值是 Throw 变量的值
Out[11]= |  |
用 Map 也可以得到同样的结果,当计算过程不是遇到 Throw 时结束,Map 的返回值是一个集合
Out[12]= |  |
用 Throw 和 Catch 可以改变函数编程结构,使得计算过程到一定条件出现时结束. 注意,用 Throw 结束的计算的结果可能会和计算全部完成得到的结果不在一样. 反复使用一个函数得到的集合
Out[13]= |  |
由于没有遇到 Throw,所以结果与前面相同
Out[14]= |  |
现在 NestList 的计算被改变,显示的是 Throw 变量的返回值
Out[15]= |  |
Throw 和 Catch 完全以一种全局的方式运行,不管哪儿或怎样出现 Throw, 它都使计算停止,回到所包含的 Catch. Throw 停止 f 计算,使 Catch 的返回值为 a,f 没有任何信息留下
Out[16]= |  |
这里定义一个当其自变量的值大于 10 时就产生 Throw 函数 此处没有出现 Throw
Out[18]= |  |
但这里在g的计算过程中产生的 Throw 返回到了所包含的 Catch
Out[19]= |  |
在小的程序中,用 Throw[ ] 和 Catch[ ] 的最简单形式是合适的, 但在包含许多块的程序中,最好用 Throw[ ] 和 Catch[ 在程序的某一块中,就 可以保证 Throw 和 Catch 也在这一块中运行. 这里内部的 Catch 用到了 Throw
Out[20]= |  |
但这里仅外面的 Catch 用到了 Throw
Out[21]= |  |
可以用模式去指定哪个 Catch 使用 Throw
Out[22]= |  |
这里保证标志是局部的
Out[23]= |  |
应该认识到当 Throw 是常数时没有必要用标志,一般来说它可以是 任何表达式. 这里内部的 Catch 用标志小于 4 的所有 Throw,继续循环,当标志达到 4 时,就用外面的 Catch
Out[24]= |  |
使用 Catch[ ] 和 Throw[ ] 时,Catch 的返回值是 True 中的 . 使用 Catch[ ] 时,Catch 的返回值是 . f 作用于 Throw 中的 value 和 tag 上
Out[25]= |  |
无 Throw 时,就不使用 f
Out[26]= |  |
一般的循环结构 Do, Nest 和 FixedPoint 等函数在 Mathematica 中用来进行循环,而 Throw 和 Catch 可以用来修改这种结构. 有时需要建立没有结构的循环, 用 While 和 For 就能方便地做到这一点,它们反复进行运算,直到某条件不成立 时停止. While 循环一直进行到条件不成 立时结束
Mathematica 的 While 和 For 函数与 C 语言中的类似,但也有些重要的区别, 例如 Mathematica 和 C 语言中逗号和分号的位置正好相反. 这是一个常用的 For 循环,i++ 使 i 增加
这是一个更复杂的 For 循环, 当条件 i^2<10 不成立时结束循环
在 While 和 For 循环中,先测试条件是否成立,然后再进行循环的计算. 当条件不成立时结束,所以循环体仅在测试条件成立时计算. 循环条件不成立,故循环体没有 进行计算 在 While 循环、 For 循环以及 Mathematica 的过程中,表达式按确定的顺序 进行计算. 可以将这种顺序看作程序执行中的控制流. 大部分情况下应该 是程序的控制流尽可能的简单. 控制流对于执行过程中产生的值依赖的越多, 理解该程序运行结构就越困难. 功能编程结构涉及非常简单的控制流.由于 While 和 For 循环中的控制流依赖于 测试条件的值,它们是较复杂的ꪱ即使在这样的循环中,控制流一般 不依赖于循环体中表达式的值. 在一些情况中,程序中的控制流受一个过程 执行中所产生结果的影响,或受循环体所产生结果的影响. 处理这种情况 的一个方法是用 Throw 和 Catch,Mathematica 也提供了修改控制流的其它函数, 这与 C 语言中的情况类似. 流程控制函数 当 t>19 时,Break[ ] 导数循环结束
当 k < 3 时, Continue[ ] 使循环跳过 t += 2 继续执行
Return[ ] 使程序退出一个函数,得到一个返回值. 可以将 Throw 看作一个非局部返回,因为它退出了整个嵌套函数列,这种特性在处理一些 错误条件时非常方便. 这里提供了一个使用 Return 的例子 当变量的值大于 5 时使用第一个 Return
Out[34]= |  |
当变量值为负时这一函数给错误提示 这里没有发现错误
Out[36]= |  |
这里产生了 Throw,Catch 的返回值是 error
Out[37]= |  |
Continue 和 Break 函数等可以使程序转到循环开始或结束循环. 有时还需要 将程序转到过程的某一处,这就需要先对该处的语句标号,再用 Goto 语句就可以转到该处去. 循环进行到 q 超过 6 时结束
只有对语句标号后才能使用 Goto 语句将程序的执行转到同一过程的标号处, 使用 Goto 语句可以简化程序结构,但程序的运行过程却复杂了一些.
|