0

我从 bash 开始,我想理解这个例子......如果你们中的一个人能帮助我理解“to_roman”函数,我将非常感激!或者如果您有一些文档需要帮助,谢谢!

#!/bin/bash
LIMIT=200
E_ARG_ERR=65
E_OUT_OF_RANGE=66

if [ -z "$1" ]
then
  echo "Usage: `basename $0` number-to-convert"
  exit $E_ARG_ERR
fi  

num=$1
if [ "$num" -gt $LIMIT ]
then
    echo "Out of range!"
    exit $E_OUT_OF_RANGE
fi  

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
num=$?
to_roman $num 90 LXXXX
num=$?
to_roman $num 50 L
num=$?
to_roman $num 40 XL
num=$?
to_roman $num 10 X
num=$?
to_roman $num 9 IX
num=$?
to_roman $num 5 V
num=$?
to_roman $num 4 IV
num=$?
to_roman $num 1 I
echo
exit
4

3 回答 3

1

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使用三个参数运行该函数。第一个是您要转换的数字(或该数字的剩余部分。第二个是该数字的因子,第三个是要打印的字符。

该程序正在使用循环。例如,如果我将参数175100和传递Cto_roman函数,它会减去150 - 100,看到结果仍然大于 0,然后打印出字母C并再次尝试。在这种情况下,它会再次尝试,但会得到 number -25。由于它小于零,因此子例程以 退出75。剩余的num=$?集合number75在这种情况下为数量)。

这是为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 -xvset +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
于 2013-10-27T17:40:29.900 回答
0

它只需要一个数字和一个“因子”以及该因子的罗马表示,然后简单地循环并吐出数字 mod(factor) 的罗马表示

于 2013-10-27T14:24:24.877 回答
0

to_roman()接受三个参数:numberfactorrchar
定义函数后脚本做的第一件事是使用参数调用它$num(在命令行中作为脚本本身的参数传入);脚本可以处理的最高系数:100;以及该因子 (C) 的罗马数字表示。
从数字中减去因子得到余数,如果余数为零或更高,则打印 rchar(本例中为 C),通过删除刚刚打印的字符的值来更新数字(此处为 100),更新其余的,然后重复。
如果您的初始数字小于 100,则第一个余数计算将小于零,因此不会打印任何内容并且值不会更改。
然后脚本处理 90。num=$?每次调用 to_roman() 之间的中间值设置$num为前一次调用的返回值。
我希望这是相当清楚的。

于 2013-10-27T15:57:04.683 回答