CGI-BBS > CGI > Perl > Perlについて構造体配列を宣言&使いたい。


カレッヂ
カレッヂ


質問者 にしかわゆき  投稿日 5/7(水) 18:04:01
こんにちは。どうしてもよい解説が見つからず、
こちらで助けてください。

C言語の構造体配列のようなデータを表現したいのですが、
どう宣言&使えばよいのか教えてください。
データは初期値をすべて同じものをセットして、初期化したいです。

流れはこれであってますか?
1.ハッシュを1つ宣言(初期値でセット)
2.そのハッシュを配列に持つ

1.のハッシュはこんな感じ。
%dat=(
      "exist" => 'NO',
      "flg"   => '',
      "cols"  => 1,
      "rows"  => 1
);
で、これを18個持つ配列にしたいので、
@array=();
for($a=0;$a<18;$a++)
{
   $array[$a]=\%dat;
}

これで、初期化できる気がするのですが。。。
すぐ後で、
print $array->[0]{"exist"};
print $array->[14]{"flg"};
とかやっても、何も表示されません。
参照が悪いのか、初期化が悪いのか・・・。

誰か教えてください。

     

プロバイダ参照:http://web.adam.ne.jp/
サーバのOS:UNIXサーバ
パソコンのOS:Win95系
エディタ:ViVi
FTPソフト:FFFTP
サーバ移転:していない
改造:(未選択)
CGI習熟度:expert

回答者 まさ  [削除]  投稿日 5/7(水) 23:02:06
%dat=(
      "exist" => 'NO',
      "flg"   => '',
      "cols"  => 1,
      "rows"  => 1
);

これがまずいですね。

Cのような構造体を表現したいのなら、ハッシュへのリファレンスを使うこと、とくに
その構築に名無しハッシュコンストラクター使うことです。

$dat = {
      exist => 'NO',
      flg   => '',
      cols  => 1,
      rows  => 1
};

こうすると上手くいきます。
構造体のメンバへのアクセスは

$dat->{exist} = 'YES';

でOK、後は自分で工夫してみて下さい。


回答者 ばくにぃ  [削除]  投稿日 9/29(月) 16:10:26
遅まきながら、レス
(最近perlを勉強しはじめて、飛んできたので(てへ

> print $array->[0]{"exist"};

が、まずいのであり、ハッシュのリファレンスを配列にする方法は、
用途があるかどうかは別にして問題は無いと思いますよ
初心者が誤解するとまずいので・・(自分はした(汗

print $array[0]{"exist"};
という表現でなかった為に、何も表示されなかっただけです。

実際に、用途を考えるなら、まささんの指摘どおりだと思います。

で、このようなことを避ける意味でも
"use strict"
を使用されることをお薦めします。
回答者 vent  [削除]  投稿日 2006/9/6(水) 17:04:23
ばくにぃさんに同じく、今更ながら。

>1.ハッシュを一つ宣言
というのが間違いだと思います。
%datを18個宣言するようにすべきではないかと。

%dat を一つしか宣言していないとすると、メモリ上でもその一箇所しか
割り当てられてません。
\%dat がある値(アドレス)で固定されてしまうので、
配列 @array に格納されるのは18項すべて同じ値(アドレス)になります。

最初に示されているコードを単純に組み合わせてみると

@array=();
for($a=0;$a<18;$a++)
{
	%dat=(
		"exist" => 'NO',
		"flg"   => '',
		"cols"  => 1,
		"rows"  => 1
	);
	$array[$a]=\%dat;
}

となります。
ちょっと見ると、for文ループによって %dat が何度も宣言されているようですが、
実はこれは間違い。

このままではやはり %dat が一つしか宣言されていないことになります。
for文の第一ループでは、%dat の宣言が行なわれていますが、
第二ループ以降では、単に上書きしているだけです。

そこで解決策として my を使います。
myを使えば、同じ変数名で変数を宣言しても新たにメモリの割り当てが行なわれます。
メモリの割り当てが行なわれることによって、\%dat の値も変わります。

@array=();
for($a=0;$a<18;$a++)
{
	my %dat=(
		"exist" => 'NO',
		"flg"   => '',
		"cols"  => 1,
		"rows"  => 1
	);
	$array[$a]=\%dat;
}

返信(回答)する

 


Web裏技