今、海外の大学に短期留学中でCSの授業をとっているのですが、その中で以下のような課題プログラムが出ています。が、Perl初心者の私にはまったく内容が理解できません。どなたか概要を解説していただけませんか?海外での英語の壁に挫折しつつあり、こちらに駆け込みさせていただきました。どうか、ご事情等ご賢察のうえ、温かいご支援をお願いいたします。
特に伺いたい点としては、以下の2点ですが全体的に解説していただけるととても助かります。
(1)この関数の呼び出し方
(2)2行目の、「my ($num, $f, @factors) = ($_[0], 2);」で、ローカル変数 $num,$f,$factors に何が初期値として代入されるのか?
sub isprime {
my ($num, $f, @factors) = ($_[0], 2);
while (1 != $num) {
if (0 == $num % $f) {
return $f == $num unless wantarray;
push @factors, $f;
$num /= $f;
} else {
$f++;
}
}
return @factors;
}
No.2ベストアンサー
- 回答日時:
ANo.1 で説明の通り、引数は数値一つです。
> @num=[4,5,6];
この代入式では、[] でくくっているので「配列の参照」を代入してます。$num[0] には、配列(4,5,6)への参照が入ります。$num[1]以降は何も無し。
> isprime(@num);
perlで関数呼び出しの引数に配列を指定した場合、配列は展開されます。この場合、@numの要素数は1つなので、isprime($num[0]) と等価。isprime は引数に数値を期待しているのに、この呼び出し方では配列への参照を与えているので、正しく動作しません。
> @num = ( 4,5,6 ); isprime(@num);
だったら、isprime(4,5,6)と等価になるので、問題なく動作しますが、引数で意味があるのは「4」だけです。5と6は無視されます。
isprimeは数値引数を取りますので、呼び出し方は、
> $result = &isprime(12);
もしくは
> @result = &isprime(12);
のどちらかになります。
wantarray は、返値を配列かスカラーか、どちらの形式で要求されているかを示します。
wantarrayは配列コンテキストで真になりますので、
上記呼び出し方法のうち、前者の場合は
> return $f == $num unless wantarray;
このreturn が実行され、
後者の場合はこのreturnは実行されませんので、最終行の「return @factors;」が実行されます。
この回答への補足
詳細なコメントありがとうございました。頂戴したアドバイスにしたがって、プログラムを実行してみたところ、このような結果となりました。
ケース1のスカラー変数の場合、引数に12を指定すると、turn値が受け取れていないようでした。また、return値を配列に格納した場合には、また違った値が格納されています。これはなぜでしょうか??呼び出し方、もしくは、値の印刷の仕方が悪いのでしょうか??教えてください。
(以下のとおり、スカラーor配列×素数、素数以外で関数を呼び出し)
ケース1:スカラー変数
$result_prime = &isprime(5);
$result_non_prime = &isprime(12);
print "scalar context :isprime(5)=$result_prime, isprime(12) =$result_non_prime\n\n";
ケース2:配列
@result_prime = & isprime(5);
@result_non_prime = &isprime(12);
print "list context :isprime(5)=$result_prime[0], isprime(12)=$result_non_prime[0]\n\n";
(実行結果)
ケース1:
scalar context :isprime(5)=1, isprime(12)=
ケース2:
list context :isprime(5)=5, isprime(12)=2
No.4
- 回答日時:
ANo.2 で書いた通り、この関数はスカラーコンテキストかリストコンテキストかで、全然別の値を返しています。
呼び出し方は間違えてないですが、返値の表示方法がちょっと間違えてます。isprimeの動作をテストするなら
foreach my $arg ( 5, 12 ) {
print "isprime($arg)\n";
my $result = &isprime($arg);
if ($result) {
print "\$result is true\n";
} else {
print "\$result is false\n";
}
my @result = &isprime($arg);
print "\@result = (@result)\n";
}
とでも実行してみてください。
ありがとうございます!早速試してみたところ、素数でない場合には、因数分解した値がリストで表示されるんですね~。ようやく、問題の意図が理解できたような気がします。頂いた動作テスト手順を実行してみて、目からウロコが落ちました。
Perlって、、、いろいろ省略できたりしてなんだかお手軽に使える言語だと耳にしていたのですが、いやいや、かなり難解です。
本当にありがとうございました。しばらくは、Perlで苦戦していると思いますので、また機会がありましたらいろいろご指導賜りたく、よろしくお願いいたします。
No.3
- 回答日時:
(1) う~ん, サブルーチンの名前から想像してほしかったんだけどなぁ.... 1個の整数が必要です.
(3) wantarray について調べてみましたか?
(4) もちろん返り値を覚えておく必要があるなら, 変数を用意して代入する必要があります.
とはいうものの, はっきりいってこのサブルーチンは出来がいいとはいえない. 特に wantarray が真のときの動作が, 名前から想像できません.
ありがとうございます。プログラミングのセンスがないことは承知していたのですが…やっぱり苦戦しています。本当に助かりました。どうもありがとうございました。
No.1
- 回答日時:
(1) サブルーチンに渡す引数は配列 @_ に入ります. このサブルーチンでは $_[0] を使っていますが, これは「配列 @_ の最初の要素」を意味しますので, 少なくとも 1個の引数が必要です.
(2) my は無視して考えてください. すると
($num, $f, @factors) = ($_[0], 2);
となりますが, このような場合には「対応する要素ごと」に代入がおきます. これで $num と $f の値は決定. @factors には「代入する値」がありませんが, そのようなときには空リストが代入されます. ちなみに @factors と $factors は別物ですので注意.
この回答への補足
早速のご回答ありがとうございます。感謝感激です。
(1)についてなのですが、具体的には、たとえば以下のように呼び出すということでしょうか?
@num=[4,5,6];
isprime(@num);
あと、以下の点も教えていただけると幸甚です。
(3)return $f == $num unless wantarray; の部分。"wantarray"とは何でしょうか?
(4)この関数は、return値(配列)を返しておりますが、この関数を呼び出す場合には、変数を定義した上でそれにreturn値を代入するようなかたちで呼び出すのでしょうか?
たとえば、以下のような呼び出し方?
@num=[4,5,6];
@result =isprime(@num);
本当に初歩的なところからの質問で恐縮ですが、どうぞよろしくお願い致します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- JavaScript JAVASCRIPT 2 2022/04/15 15:10
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# 質問です 下記のコードを分かりやすく解説お願いします 初心者です #include ‹stdio.h 3 2022/05/26 22:03
- C言語・C++・C# C言語でif文が予想と違う動きをする件について7 4 2023/03/20 00:26
- C言語・C++・C# C言語初心者 ポインタについて、お助けください、、 2 2023/03/15 23:50
- Excel(エクセル) VBA フォルダ見える化のコードについて 2 2023/06/19 15:04
- UNIX・Linux 次の要件を満たすにはどのように修正したらよろしいでしょうか 1 2022/11/24 20:57
- C言語・C++・C# C pointer? or... 2 2022/03/29 00:47
- その他(プログラミング・Web制作) このプログラミングをどう組みますか? Googlecolabでやってるんですが、出来る方お願いします 1 2022/07/13 10:52
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Perl の外部モジュールの利用方法
-
ファイルアイコンの左下に緑の□...
-
perlのプログラミング 部分入れ...
-
ペプシコーラとコカ・コーラとD...
-
アルファベットに付いて質問し...
-
#!/usr/bin/perlで書きだしたCG...
-
Perlのエラーについてご教授く...
-
perlのflock関数でロックをかけ...
-
AI sisterとは、偽物の人ですか?
-
perlプログラミング 空白行削除
-
perlでリテラル値はメモリにど...
-
perlで2次元配列をサブルーチ...
-
perlのrequireの動き方について...
-
perlの構文でカンマの意味が分...
-
perlについての質問
-
Blenderについて
-
perl このテキストファイルを簡...
-
Perlでファイルの末尾から指定...
-
秀丸での一括変換について
-
英数文字列のうちの数値を4桁に...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Can't use string ("0") as an ...
-
行指向処理でデータの読み込み...
-
サンプルの意味
-
画面を強制的に再描画させる方法
-
VBAで3秒だけ時間を止めたい
-
VBAでの一時停止と再開の方法
-
VBのReturnの使い方
-
どなたかこのプログラミングを...
-
Escキーを押すと、中断する時と...
-
UWSCの終了の仕方
-
エクセルの当番表を作っていま...
-
VBA for i=1 to lastrow
-
「偶数・奇数の和」のフローチ...
-
VBAのautofilter、criteriaの配...
-
アクティブセルから、A列最終行...
-
DoEventsが必要な理由について
-
vb.netからエクセル関数書き込み
-
GIFアニメをループさせたくない
-
DOSコマンドのループ内のTIMEコ...
-
ハッシュ検索はなぜ速い
おすすめ情報