HSP3プログラミング入門講座
powered by Let's HSP!
HSPエラー7「配列の要素が無効です」
無料プログラミングツールHSPのエラーメッセージ「HSPエラー」。
配列変数がらみで何かしらの問題が起こってる場合に表示されます。HSPエラーの番号は「7」。エディタ上のコンパイル実行では『配列の要素が無効です』のメッセージ。実行ファイルでのエラーメッセージは『内部エラーが発生しました(7)』。
配列変数は、整数値型のdim命令、文字列型のsdim命令を利用してスクリプト上で明示的に確保できます。HSP3から 実数値型(いわゆる小数点数値)としてddim命令も用意されてます。
命令の処理内容 | 1要素のサイズ | |
dim命令 | 整数値型の変数・配列変数の確保 | 4 バイト |
sdim命令 | 文字列型の変数・配列変数の確保 | 64 バイト〜 |
ddim命令 | [HSP 3.0〜] 実数値型の変数・配列変数の確保 (マクロ定義でdimtype命令に置き換え) |
8 バイト |
ldim命令 | [HSP 3.2〜] ラベル型の変数・配列変数の確保 (マクロ定義でdimtype命令に置き換え) |
4 バイト |
配列変数についてはHSPリファレンス「プログラミングマニュアル1・基本仕様ガイド (hspprog.htm) 」の 「2.スクリプト記述の基本→配列変数 」の項目をチェックあれ。下はHSPにおける変数のベーシックコード。
a = 100 // 整数値型変数 b = "HSP講座" // 文字列型変数 c = 3.14 // 実数値型変数
整数値型配列変数と文字列型配列変数のサンプル例です。
; 整数値の表示 (HSP3) // 「dim value, 7」の宣言に相当 value = 0, 1, 2, 3, 4, 5, 6 ; 要素数分だけ繰り返す foreach value mes value(cnt) * 10 loop
; 曜日文字列の表示 (HSP3) // 「sdim youbi, 64, 7」の宣言に相当 youbi = "日", "月", "火", "水", "木", "金", "土" mes "曜日番号: "+gettime(2) mes "きょうは "+youbi.gettime(2)+" 曜日だよ〜ん。"
用意した配列変数の要素数を超えている
たとえば、下のように変数valueを要素数5で確保したとすると、変数「value.0〜value.4」の範囲を利用できる ことになります。「value.5」は存在しないためエラーです。
dim value, 5 mes value.5 // ← エラー
また、HSPは代入式で配列変数(1次元のみ)を確保できます。これは「dim kazu, 4」を宣言したのに相当し、 「kazu.0〜kazu.3」の範囲です。(いわゆる変数の自動バッファ確保機能が働く)
kazu = 15, 20, 32, 46 mes kazu.2 mes kazu.6 // ← エラー
要素にありえないマイナス値が指定された場合もエラーです。
kazu = 15, 20, 32, 46 i = 3 repeat mes kazu.i // ← ループ5回目でエラー i-- loop
多次元配列変数(2次元〜4次元)は下みたいな感じでしょうか。とにかく要素数が溢れてないかチェック することをオススメします。
; 4次元 dim value, 10, 10, 10, 10 // 要素のMax value.9.9.9.9 = 500 // 従来の書式 mes value.9.9.9.9 // HSP3よりサポートした書式 (コチラの方が分かりやすい) mes value(9, 9, 9, 9)
そもそも配列変数を確保してない
上では明示的に配列変数を確保するHSPのコード(dim命令・sdim命令、代入処理)が存在しますが、確保する処理 すら用意してない場合はエラーになります。
たとえば、下の「value」変数は要素0は自動的に確保されますが、要素1、2、・・・は存在すらしないためエラーです。
mes value.0 mes value.2 // エラー
変数の型が変わってしまってる
これはちょっとした盲点ですかいな。数値型、文字列型、実数値型の宣言を行った後に異なる型のものを 代入してしまうと、最初の宣言は実質的に無意味になります。(HSP3ではvartype関数を利用してスクリプト上 で変数の型をチェックできます)
// 数値型配列変数 dim value, 5 // 文字列型で初期化してしまう value = "77" mes value.4 // ← エラー
上のような場合はint関数を利用して数値へと変換します。
// 実数値配列変数 ddim value, 5 // 整数値型で初期化してしまう value = 1 mes value.4 // ← エラー
HSP3の仕様である『計算する最初の項に合わせて、後の項が型変換されます』のため、上のような場合は小数点 数値を明示的に指定して、型が変わってしまわないようにします。(0.0を加算、1.0を乗算、double関数の利用)
その他
・ddim命令はhspdef.asファイルでマクロ定義されてるもの(実体はdimtype命令)なので、HSPスクリプトエディタ の[HSP]→[HSP拡張マクロを使用する]にチェックが入ってないと「エラー2(文法が間違っています)」です。
☆デバッグウィンドウを見よう
HSPスクリプトエディタに実装されてるデバッグウィンドウを活用しましょう。 変数タブで個々の変数の中身(状態、サイズ)をチェックできます。その際、下の[配列変数]オプションを有効に すれば、要素ごとの中身もチェックできます。
(番外編)文字列型配列変数の保存
文字列型の配列変数をbsave命令で保存しても1番目の要素しか出力されません。そのため、HSPには付属する 「hsp3util.as」モジュールにarraysave命令、arrayload命令というモジュール命令も用意されてます。この モジュール命令では要素の区切りとして改行処理を施してます。
ここでは、NULL文字($00)を区切りとしたものです。まずは出力サンプルコード。(いちおう超簡易的な暗号化処理も用意)
// 文字列型配列変数の出力保存 (by Kpan) ; 出力用データを格納するバッファの確保 ; (バッファオーバーフローしないよう要サイズ調整必須) sdim buf, 128 ; 保存する配列変数 string = "プログラミング", "HSP3", "配列変数", "保存すーるする" i = 0 foreach string ; 文字列の書き出し poke buf, i, string.cnt i + strsize ; NULL文字の書き出し poke buf, i, $00 i++ loop ; 暗号化 // gosub *encode ; 保存 bsave "hogehoge.bin", buf, i - 1 mes "done ("+strsize+" バイト)" stop *encode randomize 1234 // マジックナンバーとして任意の数値 repeat i - 1 poke buf, cnt, peek(buf, cnt) ^ rnd($100) loop return
そして、これを逆に読み込むサンプルコード。ファイルの存在有無は省略してます。
// 出力したファイルの読み込み (by Kpan) ; 取得した結果の文字列を代入する文字列型配列変数 ; (パフォーマンスを落としたくないなら要確保) sdim kekka, 64, 5 notesel data noteload "hogehoge.bin" ; 複合化 // gosub *decode i = 0 repeat ; ヘルプ説明にあるように「00というコード」で切り出し代入 getstr kekka.cnt, data, i if strsize = 0 : break i + strsize + 1 loop ; 取得結果の文字列表示 foreach kekka mes kekka.cnt loop stop *decode randomize 1234 // 指定したマジックナンバー repeat strsize poke data, cnt, peek(data, cnt) ^ rnd($100) loop return
キーワード de HSP
- 無料プログラミング
- HSPダウンロード
- 実行ファイル作成
- HSP動作環境
- 演算子
- 文字列操作
- 命令・関数一覧
- アイコン変更
- PACKFILE
- PACKFILE編集
- #packopt
- #deffunc
- HSPエラー
- HSPエラー番号
- HSPエラー7
- HSPエラー12
- HSPエラー13
- HSPエラー33
- HSPエラー38
- HSPエラー41
- ホームページ作成
- バージョン
- フォント
- オブジェクト
- ボタン
- 入力ボックス
- オブジェクト非表示
- Win32 API
- メニュー
- HSPLet
- サウンド再生
- 画像
- PNGファイル
- HSP質問掲示板
- デバッグ
- ドラッグ&ドロップ
- ブラウザ作成
- HSP書籍本