📄 recurnolocvar.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><HTML><HEAD><TITLE>不使用局部变量的递归</TITLE><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINKREL="HOME"TITLE="高级Bash脚本编程指南"HREF="index.html"><LINKREL="UP"TITLE="函数"HREF="functions.html"><LINKREL="PREVIOUS"TITLE="局部变量"HREF="localvar.html"><LINKREL="NEXT"TITLE="别名"HREF="aliases.html"></HEAD><BODYCLASS="SECT1"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#0000FF"VLINK="#840084"ALINK="#0000FF"><DIVCLASS="NAVHEADER"><TABLESUMMARY="Header navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">高级Bash脚本编程指南: 一本深入学习shell脚本艺术的书籍</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><AHREF="localvar.html"ACCESSKEY="P">前一页</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom">23. 函数</TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="aliases.html"ACCESSKEY="N">下一页</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="SECT1"><H1CLASS="SECT1"><ANAME="RECURNOLOCVAR">23.3. 不使用局部变量的递归</A></H1><P>即使不使用局部变量, 函数也可以递归的调用自身. </P><DIVCLASS="EXAMPLE"><HR><ANAME="HANOI"></A><P><B>例子 23-14. 汉诺塔</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 #! /bin/bash 2 # 3 # 汉诺塔 4 # Bash script 5 # Copyright (C) 2000 Amit Singh. All Rights Reserved. 6 # http://hanoi.kernelthread.com 7 # 8 # 在bash version 2.05b.0(13)-release下通过测试 9 # 10 # 经过脚本原作者同意 11 #+ 可以使用在"Advanced Bash Scripting Guide"中. 12 # 本书作者对此脚本做了少许修改. 13 14 #=================================================================# 15 # 汉诺塔是由Edouard Lucas提出的数学谜题, 16 #+ 他是19世纪的法国数学家. 17 # 18 # 有三个直立的柱子竖在地面上. 19 # 第一个柱子上有一组盘子套在上面. 20 # 这些盘子是平的, 中间有孔, 21 #+ 可以套在柱子上面. 22 # 这些盘子的直径不同, 它们从下到上, 23 #+ 按照尺寸递减的顺序摆放. 24 # 也就是说, 最小的在最上边, 最大的在最下面. 25 # 26 # 现在的任务是要把这组盘子 27 #+ 从一个柱子上全部搬到另一个柱子上. 28 # 你每次只能将一个盘子从一个柱子移动到另一个柱子上. 29 # 你也可以把盘子从其他的柱子上移回到原来的柱子上. 30 # 你只能把小的盘子放到大的盘子上, 31 #+ 反过来就*不*行. 32 # 切记, 这是规则, 绝对不能把大盘子放到小盘子的上面. 33 # 34 # 如果盘子的数量比较少, 那么移不了几次就能完成. 35 #+ 但是随着盘子数量的增加, 36 #+ 移动次数几乎成倍的增长, 37 #+ 而且移动的"策略"也会变得越来越复杂. 38 # 39 # 想了解更多信息的话, 请访问http://hanoi.kernelthread.com. 40 # 41 # 42 # ... ... ... 43 # | | | | | | 44 # _|_|_ | | | | 45 # |_____| | | | | 46 # |_______| | | | | 47 # |_________| | | | | 48 # |___________| | | | | 49 # | | | | | | 50 # .--------------------------------------------------------------. 51 # |**************************************************************| 52 # #1 #2 #3 53 # 54 #=================================================================# 55 56 57 E_NOPARAM=66 # 没有参数传给脚本. 58 E_BADPARAM=67 # 传给脚本的盘子个数不符合要求. 59 Moves= # 保存移动次数的全局变量. 60 # 这里修改了原来的脚本. 61 62 dohanoi() { # 递归函数. 63 case $1 in 64 0) 65 ;; 66 *) 67 dohanoi "$(($1-1))" $2 $4 $3 68 echo move $2 "-->" $3 69 let "Moves += 1" # 这里修改了原脚本. 70 dohanoi "$(($1-1))" $4 $3 $2 71 ;; 72 esac 73 } 74 75 case $# in 76 1) 77 case $(($1>0)) in # 至少要有一个盘子. 78 1) 79 dohanoi $1 1 3 2 80 echo "Total moves = $Moves" 81 exit 0; 82 ;; 83 *) 84 echo "$0: illegal value for number of disks"; 85 exit $E_BADPARAM; 86 ;; 87 esac 88 ;; 89 *) 90 echo "usage: $0 N" 91 echo " Where \"N\" is the number of disks." 92 exit $E_NOPARAM; 93 ;; 94 esac 95 96 # 练习: 97 # ----- 98 # 1) 这个位置以下的代码会不会被执行? 99 # 为什么不? (容易)100 # 2) 解释一下这个运行的"dohanoi"函数的运行原理. 101 # (比较难)</PRE></FONT></TD></TR></TABLE><HR></DIV></DIV><DIVCLASS="NAVFOOTER"><HRALIGN="LEFT"WIDTH="100%"><TABLESUMMARY="Footer navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><AHREF="localvar.html"ACCESSKEY="P">前一页</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="index.html"ACCESSKEY="H">首页</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><AHREF="aliases.html"ACCESSKEY="N">下一页</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">局部变量</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="functions.html"ACCESSKEY="U">上一级</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">别名</TD></TR></TABLE></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -