No.7ベストアンサー
- 回答日時:
配列 @a に対し $#a で「@a の最後の添字」が得られるというのはよく知られているところですが, $#a を左辺値として使うと「@a の最後の添字を決める」ことができます. 例えば
$#a = 6;
とすると, @a の大きさは (添字にして 0~6 の) 7 となります. 配列が大きくなる場合は undef で埋め, 小さくなるときには余計なところがだまって消滅します.
んで #4 の「美しくない」ってのは, map を単に「ならべる」ために使うのがうれしくないなぁ, と.
@a = ([([(0) x ($z+1)]) x ($y+1)]) x ($x+1);
とできればいいんだけど, 実は間違っている.
以下は #6 向け (笑)
perl 5.14 の場合, 代入する値が定数なら 0 でも 100 でも同じコードを吐きます. まぁ, 0 であったところで何かが簡単になるわけじゃないので, わざわざ変える必要もないでしょう. そして, 機械語の場合でも「引き算」と「排他的論理和」と「単に 0 を代入」とで, 微妙に動作が違うことがあったりする. 例えば 8080 とか Z80 とかだとフラグの変化が全て違うので, 変なことをすると「0 を代入」じゃないと動かないことがある (この辺は 8086 でも同じだったはず). 一方 68000 では「0 を代入」で十分なので, 排他的論理和を使う必要はありません (使ってもいいけど何もかわらない).
No.6
- 回答日時:
ANo.4さんのリストはなかなかすっきりしてきれいでしたので参考にさせてもらって後学の為実際に動作確認してみました。
my @a = map{[map{[(0)x($z+1)]}0..$y]}0..$x;
こんな感じで動きましたがどうでしょうか。
なかなか興味深い質問で、特定範囲の配列を定義するには範囲最大の配列に値を入れればいいなどという技とか、昔のバージョンでは動かない論理演算子「//」など学習できました。
ちなみに変数一個だけの0クリアは古典的な手法で、ネイティブなコンパイラでないperlは内部的にどうなるのかわかりませんが、排他的論理和をとるのが一番効率がいいです。
これは、機械語にしたときかなり小さいステップの命令数(アキュームレータ対象なら1命令)ですむというアセンブラ職人の技みたいなものです。
perlではこんな感じ
$a ^= $a;
Cなんかでも最適化オプションでコンパイルすると「A=0;」でも「mov A,0」とならずに「xor A」とかになっちゃいます。
実際、perl内部処理ではどうなるのか興味は尽きないところです。
化石の戯言ですのでスルーでお願いします。
No.5
- 回答日時:
$a += $b;
は本質的に
$a = $a + $b;
と同じなんだから,
$a //= $b;
は本質的に
$a = $a // $b;
と同じ.
なお, #4 は $x, $y, $z の順序を間違えてます.
参考URL:http://perldoc.perl.org/perlop.html#Logical-Defi …
No.4
- 回答日時:
@a = map { [ map { [ (0) x $x ] } 1 .. $y ] } 1 .. $z;
う~ん, 美しくない....
ありがとうございます。
ただ、私のあたまがついていきません。。。
ちなみに
if ( ($var //=0) == 3){
とやると初期化してない$varに0が入るみたいですね。
//=0 てどういう意味でしょう? +=0とのちがいは?
No.3
- 回答日時:
>Cとかだと 定義するときに = 0 とか書けますよね。
。Perlも書けます。
単に定義しないで突発的にない物を使うから書くタイミングがないだけだと思うのですが。
解決策はいくつかあります。
1: definedが未定義値かそうでないかを判別させます。
2: /^0$/ と正規表現を使用。文字列として0がひっかかるかどうか。($x eq 0 より速い)。
3: 変数内が必ず数値の場合、もう面倒なら偽なら全部0を代入する。 $x or $x = 0;
以上までが判定させる場合の処理。
その都度やらなくても、タイミング的に適切な場所で、
未定義値を0に変換する関数(もちろん配列変数を操作する関数)に飛ばすのが多くの場合よいと思う。
不可能ならその都度個別におこなう。
1: @y = (0) x $x; # $x 個の 0 で構成されたリスト値を返す。
(Perl特有の突発的な変数の発生に対応出来ないので使いにくい)。
以上は判定はさせないが先に決めておく方法。
上記のどちらも余計な行数(処理)が加わります。
ほとんどの場合、どちらも書かずに処理を作ることができます。
ただし、それはデータ構造の作り方と使い方に起因するのでここで例は示せません。
#----------------------------------
直接関係ないけど。
$array[$x][$y][$z];
は動的に定義されてるんだろうと思いますが、
定義した瞬間代入せんのですか?
それとも $x や $y の数字は飛び飛びなんですか? (0, 4, 9) みたいな。
それで$xが1だったりした時に未定義値になるんですか?
だとしたら構造に問題があると思います。
もし違うなら、存在しないものにアクセスして内部で自動生成させる時は、
なるべくその場で代入する時だけにするのがいいです。
あるのかないのか分からない物にアクセスしておいて、
あると決め付けてその場で使うのは違うと思うです。
たまにどうしてもそうゆう処理で作りたい時もありますが、
最低でも「あると決め付け」をせず、「あるのかないのか分からない」と言う前提の記述が必要です。
たいへん丁寧なご回答ありがとうございます。
配列の添え字、$x, $y, $zはとびとびではないですが、ふえていきます。
沿え字の上限はだいたいわかっているので
その分 0初期化してしまってもよいですね。
Cだと 構造体の定義文で = 0と書いておけばよかったように思いますが
Perl だと
@y = (0) x $x; # $x 個の 0 で構成されたリスト値を返す。
というのがあるのですね。ただ 多次元だとどうでしょう。
for ($x = 0; $x < 1000; $x++ ){
for ($y = 0; $y < 1000; $y++ ){
for ($z = 0; $z < 1000; $z++ ){
ということでしょうか。
No.2
- 回答日時:
実のところ「大小比較などでエラーとなることがあります」の「エラー」がどんなものか見えてないんだけど, ひょっとして autovivify がらみかな?
もしそうなら //= が最も安全な気がします. 例えば
if ($multi_dimension_array[$x][$y][$z] == 3) { # 以下省略
では autovivify できずにエラーが出たかもしれない. それ系のエラーなら
if (($multi_dimension_array[$x][$y][$z] //= 0) == 3) { # 以下省略
でごまかせる... けど面倒だなぁ. たぶんどうにもならんと思うけど.
エラーは uninitilized ....とかいうメッセージでした。
さきほどの方の助言どおり 0を足してやってますが、
//= 0) == 3) も試してみます。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Perl perlをバージョンアップしたら、今まで正常に動いていたプログラムが、エラーになってしまった 3 2022/10/05 15:44
- C言語・C++・C# プログラミングを教えて欲しいです。 配列aは、int a[9]={7,6,12,8,3,5,10,9 4 2022/12/19 23:27
- システム 外付けHDDの初期化について 4 2023/03/05 20:00
- システム 外付けHDDの初期化について 4 2023/03/05 21:19
- C言語・C++・C# C言語初心者 ポインタについて、お助けください、、 2 2023/03/15 23:50
- C言語・C++・C# 配列の初期化についてです。 int 例のプログラムで int x[5]={1,2,3,4,5}; x 1 2022/05/29 15:00
- ノートパソコン 初期化する方法を教えて欲しい。 2 2023/01/06 14:49
- Visual Basic(VBA) Excel のユーザー定義関数でソルバーが動作しない 1 2022/09/05 19:51
- ゲーム ps4について ps4最新型プロを先日友達からもらいました。はじめてのps4なので色々よくわかりませ 2 2022/12/06 06:35
- Windows 10 Windows11 を初期状態に戻す方法について。 2 2022/11/21 20:09
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
マクロの書き換え箇所がわかり...
-
なぜかわかりませんscanf()の戻...
-
$template->output();の時に ...
-
配列へのポインタの代入
-
ポインター引数の関数でコンパ...
-
10Mバイトて文字数に すると何...
-
UTF-8で5~6バイトになる文字コ...
-
エクセルシート名の制限を変更...
-
COBOLのCOMP形式について
-
【Excel VBA】10進数を2進数に...
-
バイナリとBCDコード
-
char str[256]の256の意味は?
-
ビットスワップとバイトスワッ...
-
stable diffusionのエラー
-
printfの%eで指数部分の桁数を...
-
Excel VBA メール作成について ...
-
htmlソース編集で、各タグを何...
-
DataGridViewの特定列に入力さ...
-
:(コロン)のKeyCode
-
Visual Basicでパック10進(2進...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
pythonにCでのexternはありますか
-
python 3.10で 同じlistに同じ...
-
CSVから構造体へ代入
-
VBScriptでカレントディレクト...
-
マクロの書き換え箇所がわかり...
-
Perlで変数中のエスケープされ...
-
c言語 グローバル変数
-
なぜかわかりませんscanf()の戻...
-
UWSCにおける変数の扱い方
-
VB2010での連立方程式の計算
-
ポインター引数の関数でコンパ...
-
10Mバイトて文字数に すると何...
-
UTF-8で5~6バイトになる文字コ...
-
Excel VBA メール作成について ...
-
char str[256]の256の意味は?
-
エクセルシート名の制限を変更...
-
stable diffusionのエラー
-
COBOLのCOMP形式について
-
Excel 1セル当りの文字数が2...
-
DataGridViewの特定列に入力さ...
おすすめ情報