- 締切済み
サブルーティンの使い方。
サブルーティンの理解を深めるために、 階乗の計算をサブルーティンで行うプログラムを作りました。 自作のプログラムについて質問を二つしたいと思います。 1.一応、計算は出来るのですが、 定型的でないというか、無駄が多いというか、 何か違う気がするのです。 どこか変なところはありませんでしょうか? 2.エラーメッセージをどこにいれたらいいのかわかりません。 数字以外、(例えば文字)が入力されれば1が出力されるようにはしたのですが、 「これは数字ではありません」のようなエラーメッセージを出したいのです。 この場合はどこにどのように記述すればいいですか? 色々試してみたのですが、思い通りに動きませんでした。 みなさま、知恵をお貸しください。 ------------------------------------------- use strict; print "数字を入力してください。\n"; chomp( my $number = <STDIN> ); my $k_number = kaijo($number); print "入力された数字の階乗は$k_numberです。\n"; sub kaijo { my $number = shift @_; return undef if $number < 0; return 1 if $number == 0; my $kaijo = 1; for(my $i = $number; $i>1; $i--) { $kaijo *= $i; } return $kaijo; }
- みんなの回答 (5)
- 専門家の回答
みんなの回答
- sample_
- ベストアンサー率76% (20/26)
ちょっぴり便乗させていただいて… 階乗の計算を1..$hogeのリストをforで計算 するってのもよいかもしれませんねぇ。 ---------------------------------------------------------- use strict; use warnings; print "数字を入力してください。\n"; chomp($_ = <>); die "これは数字ではありません\n" unless /^\d+$/; printf("入力された数字の階乗は%dです。\n", &kaijo($_)); sub kaijo { my $num = 1; $num *= $_ for(1..$_[0]); return $num; } ----------------------------------------------------------
試しに書いてみました。 参考になれば幸いです。 ------------------------------- #!/usr/bin/perl use strict; print "数字を入力してください。\n"; chomp($_ = <>); die "これは数字ではありません\n" unless /^\d+$/; printf("入力された数字の階乗は%dです。\n", &kaijo($_)); sub kaijo { my $n = shift; my $kaijo = 1; for(my $i = 2; $i <= $n; $i++){ $kaijo *= $i; } return $kaijo; }
- Tacosan
- ベストアンサー率23% (3656/15482)
サブルーチン check の条件は unless ($input =~ /^[0-9]+$/) くらいでいいと思うよ>#2. もしくは if ($input =~ /[^0-9]/) でもたぶん可. ちなみに「check」とか「test」などの名前にするのは「どのような時に条件が成り立つのか」がわかりにくいのでやめた方がいいです.
- k17s
- ベストアンサー率47% (9/19)
素人ですので参考程度に。 1.そこまで気になるところはないと思います。 ただエラー処理をするようであればkaijoルーチン内での return undef if $number < 0; return 1 if $number == 0; がいらなくなりそうですね。 ほかの処理も短く書く事は可能だとは思いますが、短くて読みにくいソースより個人的には多少長くても見やすいソースが読みやすいので良いと思います。 http://jamz.jp/tech/2007/12/coding-style-in-perl.html 2.エラー処理ですが、サブルーチン内でチェックする、kaijoルーチンに渡す前にチェックする、チェック専用ルーチンを作る等あるとは思いますが、サブルーチンの勉強との事でチェックルーチンを作ってみました。 use strict; my $k_number; $k_number = input(); print "入力された数字の階乗は$k_numberです。\n"; sub input { my $number,$k_number; print "数字を入力してください。\n"; chomp( $number = <STDIN> ); return kaijo($number) if check($number); } sub check { my $number = shift; if($number =~ /^[^0-9]+$/) { print "$numberは数字ではありません\n\n"; input(); } return 1; } sub kaijo { my $number = shift; my $kaijo = 1; for(my $i = $number; $i>1; $i--) { $kaijo *= $i; } return $kaijo; } 参考になればと思います。
- Tacosan
- ベストアンサー率23% (3656/15482)
1.まあ, 大体こんなもんじゃないかな. しいて言えば最初の my $number = shift @_; は my $number = shift; か my ($number) = @_; か, くらい? for を foreach にする手もあるけどあんまり変わらんし. 2.最初の return の前に「数字じゃなかったら」という文を入れるんだけど.... ちなみにどのような文を試してみたんでしょうか?