なにやらむつかしそうなタイトルですが、結構簡単です。
では始めましょ〜。
今回は、変数を a000 〜 a999 まで、1000個ほど使ってみようと思います。
とりあえず、連番に初期化してみましょう。
a000 = 0 a001 = 1 a002 = 2 a003 = 3 a004 = 4 a005 = 5 a006 = 6 a007 = 7 a008 = 8 a009 = 9 a010 = 10 a011 = 11 a012 = 12 a013 = 13 a014 = 14 a015 = 15 a016 = 16 a017 = 17 a018 = 18 a019 = 19 a020 = 20 a021 = 21 a022 = 22 a023 = 23 a024 = 24 a025 = 25 a026 = 26 a027 = 27 ...
残念、寿命が尽きてしまいました。(早っ!!)
というわけで、配列変数を使います。
これは、変数に連番を振って、同時に管理しようというモノです。
早速、配列変数を作ってみましょう。
dim a, 1000 // 要素数 1000 の int型配列
完成です。実行しても何も動きませんが。
これで、あっという間に大量の変数を管理できます。
イメージとしては、こんな感じ。
変数の箱が、一直線に並んでいます。
この箱の一つ一つを要素(element)、要素の数を要素数(length, size, count, など)といいます。
また、要素を識別するための番号を添字(index)といいます。
一つの配列に含まれる要素は、すべて同じ型でなければなりません (面倒な仕様ですが)。
見ての通り、0から始まる連番です。
1からではないので、注意してください (よく間違えます)。
※余談ですが、数学で「自然数 (N; Natural Number)」に 0 を含めるという流派もあります。
dim 命令は int 型の配列変数を作ります。
str型ならsdim、
double型ならddimを使います。
どんな型の変数でも配列にする場合は、dimtype 命令を使います (普通は使いません)。
// 配列変数を作ってみる ( 作るだけ編 ) *main dim array_int, 4 // int 型 sdim array_str, , 5 // str 型 (p2 を無視) ddim array_double, 6 // double (ddim だけは、命令ではなくマクロ) dimtype array_label, vartype("label"), 7 // label 型 ( 詳しくは後述 ) stop
特に何も起こらない
sdim命令は、第二パラメータが要素数ではないので気を付けてください。
p2 には、各要素が「文字列を持つために予め用意する領域」(= バッファ)の大きさを指定しますが、これは代入するときに自動的にやってくれるので、普通気にする必要はありません。
次元、という言葉を聞いたことがありますか? ( Jigen is dimension in English. )
〜D というやつで、現実世界は 3D です。
この D は dimension (次元) の D で、3Dは3次元のことです。
次元数 | 内容 |
---|---|
0 (?) | 点 |
1 | 線 |
2 | 平面 |
3 | 立体 |
4 | 22世紀のポケット |
こんな風になっています。
さっき作った、一直線に並ぶ配列変数は、一次元なので、一次元配列変数と呼びます。
二次元以上の場合は、多次元配列変数と言います。( 二次元配列、三次元配列などとも言います。)
HSPでは四次元配列変数まで扱えますが、想像するのが難しく、僕は使ったことがありません。
せめて三次元までです。三次元も滅多に使いませんが……。
二次元配列変数も、変数名に ( ) をつけて参照しますが、( ) の中に数値を、',' で区切って2つ書きます。( 後ろの方は省略可能。省略したときは 0 )。
二次元配列に ( x, y, z ) と、3つも書くことはできません。( 三次元配列ならOK )
// 二次元配列の参照 dim array, 3, 3 // int 型、要素数 5 の配列 array(1, 2) = 3 // 次の5行を、一気に行います。
配列にたくさんの値を一気に代入する、便利な構文があるので、紹介しておきます。
これを僕は「連続代入」と呼びます。
// 一次元配列への連続代入 *main dim array, 5 // int 型、要素数 5 の配列 // 配列の連続代入 array = 4, 6, 8, 10, 12 // 次の5行を、一気に行います。 ; array(0) = 4 ; array(1) = 6 ; array(2) = 8 ; array(3) = 10 ; array(4) = 12 gosub *ShowArrayValue // 途中から連続代入 array(2) = 67, 93, 45, 77 // 要素数は自動的に拡張される( 代入時のみ ) ; array(2) = 67 ; array(3) = 93 ; array(4) = 45 ; array(5) = 77 // 自動的に配列の要素数が6になる gosub *ShowArrayValue ; mes array(length(array)) // 要素番号が大きすぎる。添字の最大は 要素数 - 1 mes array(length(array) - 1) // 最後の要素 mes array(0) // 最初の要素 mes array // () がなければ (0) になるHSPの優しさ(緩さ?)はすばらしい。 stop // 変数の内容を表示 *ShowArrayValue mes "Show Array Value : 要素 "+ length(array) +" 個" // length()関数は、配列の要素数を返す // 配列の一次元目の要素数の分だけループする foreach array mes "array("+ cnt +") = "+ array(cnt) loop mes return
// 多次元配列への連続代入 *main dim array, 4, 2 // int、要素数[4][2]の配列 // 配列の連続代入 array = 4, 6, 8, 10 // 次の4行を、一気に行う ; array(0, 0) = 4 // 二次元目が 0 なら、省略可能。(0, 0) はなくてもいい ; array(1, 0) = 6 // array(1) = 6 ; array(2, 0) = 8 ; array(3, 0) = 10 // 途中から連続代入 array(2, 1) = 99, 0xFF // 連続代入は、二次元配列でも可能 ; array(2, 1) = 99 ; array(3, 1) = 0xFF gosub *ShowArrayValue // エラー (error) を起こす array(2, 1) = 99, 0xFF, 45 // 二次元配列の場合、自動的な拡張はしてくれない stop *ShowArrayValue // 変数の内容を表示 mes "Show Array Value : 要素 "+ length(array) +" 個" // length 関数は、配列の要素数を返す i = 0 repeat length2(array) // 二次元目の要素数 repeat length(array) // 一次元目の要素数 mes "array("+ cnt +", "+ i +") = "+ array(cnt, i) loop i ++ loop mes return
こんな感じです。添字が 0 から始まるところさえ覚えておけば、さして難しくはないでしょう。
おまけですが、添字の指定にこんなことも出来ます。
古いバージョンのHSP(2.x系)では、これが使われていました。
// HSP2.x でも実行できるサンプル *main dim array, 20 repeat 20 array.cnt = cnt * 3 // 配列変数名.添字 loop repeat 20, 1 // cnt == 1 から始める mes array.(cnt - 1) // 添字に式を使う場合は () が必要 ; mes array(cnt + 1) // 素直にこっちでいいじゃないか loop // ちなみに、多次元では array.a.b.c.d とします。 stop
by 上大