Home -> HSP講座 -> 初級編 No.13

管理者になる

なにやらむつかしそうなタイトルですが、結構簡単です。
では始めましょ〜。


番号を付けて管理しよう

今回は、変数を 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)といいます。
一つの配列に含まれる要素は、すべて同じ型でなければなりません (面倒な仕様ですが)。

見ての通り、から始まる連番です。
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次元のことです。

次元数 内容
(?)
平面
立体
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 上大

第十二章へ   第十四章へ