はto_roman ()
関数定義であり、プログラム自体の一部ではありません。実際のプログラムはその下から始まります。
の前to_roman ()
に、プログラムは単に入力を検証しています。パラメータを含めましたか?そうでない場合は、最初のif
ステートメントがそれをキャッチします。
数は 200 を超えていますか? 200 より大きい場合は、2 番目if
が処理します。
プログラムの核心は次のとおりです。
to_roman $num 100 C
num=$?
to_roman $num 90 LXXXX
num=$?
to_roman $num 50 L
num=$?
プログラムはto_roman
、3 つのパラメーターを使用して関数を実行しています。1 つ目は変換したい数値 (またはその数値の残り) です。2 つ目はその数値の係数で、3 つ目は出力する文字です。
プログラムは、ループを使用しています。たとえば、パラメータ175
、100
、およびC
をto_roman
関数に渡すと、 が減算され150 - 100
、結果がまだ 0 より大きいことがわかり、文字が出力されてC
再試行されます。この場合、もう一度試行しますが、番号を取得します-25
。ゼロ未満なので、サブルーチンは で終了し75
ます。残り物(この場合は金額)のnum=$?
セット。number
75
これは(は 0 より小さいto_roman 75 90 LXXXX
ため何も表示されません)、 ( 75 から1 を引くことができるため1 を表示します) に対して行われます。その最後の結果は です。90 - 75
to_roman 75 50 L
L
50
25
シェル スクリプトを理解するためにできることを次に示します。初め:
$ export PS4="\$LINENO: "
PS4
プロンプトはデバッグ用です。デフォルトのPS4
プロンプトは+
あまり役に立ちません。これにより、PS4
デバッグ中のシェル スクリプトの行番号にプロンプトが変更されます。
ここで、デバッグしようとしているシェル スクリプトの領域を配置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