プロが教える店舗&オフィスのセキュリティ対策術

perlを勉強中ですc言語は大体理解できます。
標準入力から2次元配列の行数と列数を読み込んで、
さらに標準入力からその2次元配列の各要素を読み込み、
その2次元配列をサブルーチンに値渡ししたいのですが、
変数の使い方をどのようにしたらいいかわかりません。
実現方法を教えて!goo

A 回答 (5件)

https://perldoc.jp/docs/perl/5.36.0/perldsc.pod
や関連資料で勉強しましょう。


C言語は大体理解できる、ということなので、Cの配列と同じようにPerlの配列を考えているように思えます。


作ろうとしているプログラム、まるでC言語の練習問題のみたいですが

たしかに、C言語でやるなら、
サイズを入力→mallocで必要なサイズを用意
となるでしょう。

対して、Perlの配列は伸縮自在です。
my @a ;
で空の配列を用意して
print $a[5] ;
としてもまったく問題ありません。(値は未定義値(undef)になります。)
$a[8] = 5 ;
とすると、@aのサイズが勝手に増えます。
(C言語のような)他の変数の領域にアクセスする、といったことは発生しますん。
https://perldoc.jp/docs/perl/5.36.0/perlfunc.pod
push,pop,shift,unshit、splice等で追加削除できます。

Perlでは配列のサイズ、配列自身から簡単に調べることができます。
Cにように別途渡す必要はありません。
全ての要素を順番に処理するなら、 foreach 構文も使えます。


C言語のやり方は参考になりますが、それに固執してPerlでやろうとするとかえって難しくなることがあります。
Perlの特徴を理解し、Perlでやりやすい方法を考えるのがよいでしょう
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
おっしゃる通り、あるプログラム入門サイトの問題なのです^ー^うまくいかず質問した次第です。
C言語と違ってperlは独特な自由な感じなのでなかなか難しいですが教えていただいたサイトを見て色々試してみたいと思います。
ありがとうございました。

お礼日時:2022/12/18 17:34

「値渡し」かどうかと「標準入力から2次元配列の行数と列数を読み込んで」うんぬんとは無関係なんだ.



で「値渡し」が「サブルーチンの中で配列中の値を変更しても元の配列では値が変わらないようにしたい」ということなら, 例えば
https://kasei-san.hatenadiary.org/entry/20081121 …
のようにがんばって deep copy するしかないと思う.
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
やはり全部中でコピーするしかないのですね。頑張ります。

お礼日時:2022/12/18 19:39

サンプルです。


my $var = <STDIN>;
chomp($var);
(my $row,my $col) = split(/\s+/,$var);
print "row=$row column=$col\n";
my @arr = ();
for (my $i = 0; $i < $row; $i++){
$var = <STDIN>;
chomp($var);
my @line = split(/\s+/,$var);
if (scalar(@line) != $col){
print "invalid column size\n";
exit(10);
}
for (my $j = 0; $j < $col; $j++){
$arr[$i][$j] = $line[$j];
}
# 下記行でも同じ結果になる
#$arr[$i] = [@line];
}
print "---main ----\n";
for (my $i = 0; $i < $row; $i++){
for (my $j = 0; $j < $col; $j++){
print "$arr[$i][$j] ";
}
print "\n";
}

pout(\@arr);

sub pout{
(my $arr_ref) = @_;
my @p_arr = @$arr_ref;
my $p_row = scalar(@p_arr);
my $p_col = scalar(@{$p_arr[0]});
print "---pout----\n";
print "row=$p_row column=$p_col\n";
for (my $i = 0; $i < $p_row; $i++){
for (my $j = 0; $j < $p_col; $j++){
print "$p_arr[$i][$j] ";
}
print "\n";
}
}
-----------------------------------------
実行結果
2 3  ・・・入力
row=2 column=3
aa bb cc  ・・・入力
dd ee ff  ・・・入力
---main ----
aa bb cc
dd ee ff
---pout----
row=2 column=3
aa bb cc
dd ee ff

補足
2は行数 3は列数です。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
サンプル動かしてみました。mainとpoutで同じ出力になりました。
しかし、値渡しではなく自分もよく理解できていないリファレンス(参照?)渡しになっているみたいで、poutの中で値を変更すると、poutから抜けても元の値に戻らず変更した値のままでした。値渡しする方法はあるでしょうか。

お礼日時:2022/12/18 17:29

「各要素が配列へのリファレンスであるような配列」というのは結局のところ「配列」なんだから, 本質的には「1次元」のときと何もかわらない.



んだけど, なにをいっているのかわからないところがさしあたり 2点ある.
・「動的に受け取る」ってどういうこと? 「誰が」「誰から」「何を」動的に受け取るのかな?
・「標準入力から受け取ったサイズは受け取るまでサイズがわからない」は日本語として意味がわからない. 標準入力から例えば「18」という「サイズ」を受け取るとして, 「18」という値ではなく (その「18」という値の属性としての) 「サイズ」とやらがわからないっていう文章なんだよね. でも, その意味の「サイズ」ってなんの意味があるの?
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
なにやら考えが曖昧な段階で質問をしてしまって混乱させてしまってすみません。もっと勉強して意図する事を伝えれるようになってから質問したいと思います。(意図を汲み取ってもらえるんじゃないかという甘えがありましたすみません><リファレンスもよくわかっていません><)
・動的に受け取るというのはプログラムが標準入力から2次元配列のデータを受け取る際にどのような変数で受け取ればいいかということです。
・サイズがわからないというのはプログラムを記述する段階では標準入力から受け取る2次元配列のデータの大きさがわからないから、どういう変数で受け取ったらいいかがよくわからないです。
初心者ですが頑張りたいと思います。よろしくお願いします。

お礼日時:2022/12/18 17:01

「各要素が配列へのリファレンスであるような配列」を作ってもいいし, 「各要素が配列へのリファレンスであるような配列リファレンス」を作ってもいい.



ちなみに「2次元配列」ではなくて「1次元配列」だとしたらどうしてる?
    • good
    • 0
この回答へのお礼

回答ありがとうございます
ネットで調べたらやはりリファレンスを使うとのことでしたが、標準入力から受け取ったサイズは受け取るまでサイズがわからないので、動的に受け取るやり方がよくわかりません。
配列を渡すときは1次元が1つだけだったら引数の一番最後に配列を渡すとうまく渡すことができると思います。

お礼日時:2022/12/18 00:21

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!