这to_roman ()
是一个函数定义,而不是程序本身的一部分。实际的程序从下面开始。
之前to_roman ()
,程序只是验证您的输入。你包括一个参数吗?如果没有,第一个if
语句将捕捉到这一点。
数字是否大于 200?如果它大于 200,则第二个if
将处理该问题。
该计划的核心是:
to_roman $num 100 C
num=$?
to_roman $num 90 LXXXX
num=$?
to_roman $num 50 L
num=$?
该程序正在to_roman
使用三个参数运行该函数。第一个是您要转换的数字(或该数字的剩余部分。第二个是该数字的因子,第三个是要打印的字符。
该程序正在使用循环。例如,如果我将参数175
、100
和传递C
给to_roman
函数,它会减去150 - 100
,看到结果仍然大于 0,然后打印出字母C
并再次尝试。在这种情况下,它会再次尝试,但会得到 number -25
。由于它小于零,因此子例程以 退出75
。剩余的num=$?
集合number
(75
在这种情况下为数量)。
这是为to_roman 75 90 LXXXX
(它不会打印出任何东西,因为90 - 75
它小于零),to_roman 75 50 L
(它会打印出一个单曲,因为你可以从 75L
中减去一个单曲)。50
最后一个的结果是25
。
您可以采取以下措施来帮助您理解 shell 脚本。第一的:
$ export PS4="\$LINENO: "
提示PS4
用于调试。默认PS4
提示+
不太有用。这会将PS4
提示更改为正在调试的 shell 脚本的行号。
现在,将您尝试调试的 shell 脚本区域放在周围set -xv
。set +xv
在这种情况下,您可能希望将其放在脚本的开头和结尾。这是我的调试输出,编号为 175。看看您是否可以了解正在发生的事情:
$ ./roman.sh 175
LIMIT=200
3: LIMIT=200
E_ARG_ERR=65
4: E_ARG_ERR=65
E_OUT_OF_RANGE=66
5: E_OUT_OF_RANGE=66
if [ -z "$1" ]
then
echo "Usage: `basename $0` number-to-convert"
exit $E_ARG_ERR
fi
7: '[' -z 175 ']'
num=$1
13: num=175
if [ "$num" -gt $LIMIT ]
then
echo "Out of range!"
exit $E_OUT_OF_RANGE
fi
14: '[' 175 -gt 200 ']'
to_roman ()
{
number=$1
factor=$2
rchar=$3
let "remainder = number - factor"
while [ "$remainder" -ge 0 ]
do
echo -n $rchar
let "number -= factor"
let "remainder = number - factor"
done
return $number
}
to_roman $num 100 C
35: to_roman 175 100 C
22: number=175
23: factor=100
24: rchar=C
25: let 'remainder = number - factor'
26: '[' 75 -ge 0 ']'
28: echo -n C
C29: let 'number -= factor'
30: let 'remainder = number - factor'
26: '[' -25 -ge 0 ']'
32: return 75
num=$?
36: num=75
to_roman $num 90 LXXXX
37: to_roman 75 90 LXXXX
22: number=75
23: factor=90
24: rchar=LXXXX
25: let 'remainder = number - factor'
26: '[' -15 -ge 0 ']'
32: return 75
num=$?
38: num=75
to_roman $num 50 L
39: to_roman 75 50 L
22: number=75
23: factor=50
24: rchar=L
25: let 'remainder = number - factor'
26: '[' 25 -ge 0 ']'
28: echo -n L
L29: let 'number -= factor'
30: let 'remainder = number - factor'
26: '[' -25 -ge 0 ']'
32: return 25
num=$?
40: num=25
to_roman $num 40 XL
41: to_roman 25 40 XL
22: number=25
23: factor=40
24: rchar=XL
25: let 'remainder = number - factor'
26: '[' -15 -ge 0 ']'
32: return 25
num=$?
42: num=25
to_roman $num 10 X
43: to_roman 25 10 X
22: number=25
23: factor=10
24: rchar=X
25: let 'remainder = number - factor'
26: '[' 15 -ge 0 ']'
28: echo -n X
X29: let 'number -= factor'
30: let 'remainder = number - factor'
26: '[' 5 -ge 0 ']'
28: echo -n X
X29: let 'number -= factor'
30: let 'remainder = number - factor'
26: '[' -5 -ge 0 ']'
32: return 5
num=$?
44: num=5
to_roman $num 9 IX
45: to_roman 5 9 IX
22: number=5
23: factor=9
24: rchar=IX
25: let 'remainder = number - factor'
26: '[' -4 -ge 0 ']'
32: return 5
num=$?
46: num=5
to_roman $num 5 V
47: to_roman 5 5 V
22: number=5
23: factor=5
24: rchar=V
25: let 'remainder = number - factor'
26: '[' 0 -ge 0 ']'
28: echo -n V
V29: let 'number -= factor'
30: let 'remainder = number - factor'
26: '[' -5 -ge 0 ']'
32: return 0
num=$?
48: num=0
to_roman $num 4 IV
49: to_roman 0 4 IV
22: number=0
23: factor=4
24: rchar=IV
25: let 'remainder = number - factor'
26: '[' -4 -ge 0 ']'
32: return 0
num=$?
50: num=0
to_roman $num 1 I
51: to_roman 0 1 I
22: number=0
23: factor=1
24: rchar=I
25: let 'remainder = number - factor'
26: '[' -1 -ge 0 ']'
32: return 0
echo
52: echo
set -xv
53: set -xv
exit
54: exit