FreeBASIC マニュアルのトップに戻る

FreeBASIC 配列への序論

目次→教本→いっしょに学ぼうIntroduction To Arrays←オリジナル・サイト

配列への序論 左にメニュー・フレームが表示されていない場合は、ここをクリックして下さい

←リンク元に戻る プログラム開発関連に戻る

配列は、FreeBasicで利用できる、おそらく最も便利なプログラミング構造物です。
プログラミングの技術で解決しようとする問題の多くは、表形式で配置できるデータが含まれます。配列は、このデータ形式を管理するのに最適です。
配列を理解することは、有能なプログラマになるための、重要な技能です。

配列は、単一、あるいは、複合のデータ型の、連続的なメモリ・セグメントです。
配列は、データの行と列でできた表として、考えることができます。
配列は、1つ以上の行を持つことができます。そして、各行は、1つ以上の列を持つことができます。
行と列の数は、配列の次元を定義します。
FreeBasic は、配列で、行優先の配置を用います。これは、複数の次元の配列で、最初の次元は、行に参照をつけることを意味します。
FreeBasic は、最大 8 次元の配列をサポートします。


1次元配列

一行だけの配列を、1次元配列と呼びます。
配列が、一次元の配列であれば、行は、宣言で定義されません。一行に含まれる、列の数だけを宣言します。
配列は、最低1つの行を必要とするので、この場合、行の数を指定していなくても行が存在することが、理解されます。
下の短いコードは、一次元整数配列を作成します。FreeBasic で使える配列定義方法のふたつの例です。

Dim myArray(10) As Integer

Dim myArray(1 To 10) As Integer


最初の方法は、一行、11列の配列を定義します。列番号(数値)は、0〜10 の範囲になります。
2番目の方式は、To キーワードを使って下限と上限を定義します。 ここで、インデックスは、1〜10 の範囲になります。


1次元配列インデックス

インデックス値を使って、配列の各要素にアクセスします。
一次元配列では、インデックスは、デフォルト行の列番号を参照します。
形式は、インデックスを丸括弧で囲んだ、配列変数を使います。

myArray(5) = 7

これは、配列の列 5 に、7 を設定します。

myInt = myArray (5)

これは、myInt の値に、myArray の列 5 の現在の値を、設定します。

2次元配列

2次元配列は、定義された列とともに,1つ以上の行を持つ配列です。
2次元配列は、表に似ています。定義された数の行があって、各行は、定義された数の列を持っています。
下の短いコードは、デフォルト形式を使って、配列を定義しています。

Dim myArray(2, 10) As Integer

最初の次元は、配列の行の数を定義します。2番目の次元は、各行の列数を定義します。
この例では、配列は、0〜2 に付番された 3つの行を持っています。そして、各行には、0〜10 に付番された、11の列があります。

また、配列の下限と上限を使って定義することもできます。

Dim myArray(1 To 2, 1 To 10) As Integer

この定義は、1〜2 の番号の 2つの行と、1〜10 の番号の 10 の列を設定します。

2次元配列インデックス

2次元配列の配列の要素にアクセスするには、2つのインデックスを使います。
最初のインデックスは行を選択します。そして、2番目のインデックスは、その行の中で列を選択します。

myArray(1, 5) = 7

このコードは、1行の 5列に、7 を設定します。

myInt = myArray (1, 5)

このコードは、myInt に、配列の、行 1 の列 5 の中に含まれる現在の値を設定します。

多次元の配列

3つ以上の次元の配列について、上で述べたものと同じ構文を使います。もちろん、配列次元の進行を考慮に入れます。
3次元の配列では、最初の次元は行、二番目は列、三番目は、各列の z-オーダー、つまり奥行きになります。

例えば、空間で立方体を定義するのに、x,y,z 形式を使用するでしょう。ここでは、y が縦軸を定義して、x が水平軸を定義して、z が深度軸を定義します。
この形式で配列を作成するには、配列を下のように定義します:

Dim myCube(y, x, z) As Integer


MyCube(10、10、10) は、0〜10の、垂直な11個のユニット、0〜10の、水平な11個のユニット、0〜10の、10の深さがある、立方体を作成します。
この立方体の中心にアクセスするためには、iCenter = myCube(5, 5, 5) を使います。

高度な数学上の計算を行わない限り、たぶん、3次元以上の配列を使う必要はないでしょう。
もちろん、より高い次元の配列を使う必要があるなら、同じ原則が適用されます。


動的配列

上で説明した配列は、静的配列です。 配列のサイズは、プログラムの実行中に、変更できません。
また、実行中にサイズを変えることができる、動的な配列を作ることもできます。
動的配列は、スタックや待ち行列などの、データ構造を作るために、役に立ちます。

上で説明した静的配列は、積み重ねたもの(ヒープ領域)で保たれます。しかし、動的配列は、コンピュータのメモリのプールから割り当てられます。
コンパイラは、動的に、メモリを、配列の要求された次元に基づき、配列のために、割り当てます。

ReDimキーワードを使って、動的配列を指定します。

ReDim myArray(1 To 5, 1 To 5) As Integer


プログラム実行の始めで、必要な配列の範囲が分からない場合は、空のインデックスで配列を定義できます。

Dim myArray() As Integer


この場合、コンパイラは、配列サイズのために、0 のデフォルト値を設定します。
そして、プログラムのどこかの場所で、ReDim を使って、配列の範囲を設定できます。


ReDim と ReDim Preserve

動的配列は、実行の間で、サイズを変えることができます。
ReDim は、配列の内容を消去して、デフォルト・データ型の値にします。
ReDim Preserve は、配列のサイズを、前のサイズより小さくしない限り、既存の内容をそのまま保ちます。


配列関数

配列で使える、多くの functions があります。


複合型の配列

型の定義を使うと、関連するデータを一つのエンティティに集めることができます。 そして、多くの場合、データを完全に表現するために、型の複数のインスタンスが必要になります。
型の配列を使うと、型定義の複数のインスタンスを作成できます。型定義は、配列関数を使って、容易に管理できます。
この使い方の例は、RPG(Report Program Generator)の在庫システム、編集者の中の一連の文書記述、ランダム・アクセス・データベースからの従業員記録のセットなどがあります。

型の配列を作成します。ちょうど組み込み(intrinsic)データ型の場合と同様です。
下の短いコードは、構文の例です。

Type myPoint
    row As Integer
    col As Integer
End Type

Type myLine
    p1 As myPoint
    p2 As myPoint
    char As String * 1
End Type

Dim myLineSet (1 To 3) As myLine


コードは、終点が p1p2 の、3行の組を定義します。
各終点は、row と col にあります。
配列インデックスとドット演算子の組み合わせを使って、配列要素にアクセスします。

myLineSet(1).p1.row = 1
myLineSet(1).p1.col = 1
myLineSet(1).p2.row = 10
myLineSet(1).p2.col = 10
myLineSet(1).char = Chr (219)



型の配列

複合型の配列を作成できるだけではなく、複合型の中の項目として、配列を持つことができます。
上記の例は、p1 と p2 を配列に置き換えることで、より効率的に書くことができます。

Type myPoint
    row As Integer
    col As Integer
End Type

Type myLine
    pts(1 To 2) As myPoint
    char As String * 1
End Type

Dim myLineSet (1 To 3) As myLine


ここで、pts は、myPoint の配列です。
この構造にアクセスするために、インデックスとドット演算子の組み合わせを使います。

myLineSet(1).pts(1).row = 1
myLineSet(1).pts(1).col = 1
myLineSet(1).pts(2).row = 10
myLineSet(1).pts(2).col = 10
myLineSet(1).char = Chr (219)


myLineSet は、配列なので、インデックス値を使います。
pts は、型の要素なので、ドット演算子を使って、修飾する必要があります。
しかし、pts は、また、配列なので、それぞれの pts 配列要素を選択するのに、インデックスを使います。
行と列は、myPoint 型の要素であり、ドット演算子でアクセスされます。

終点に配列を使うと、線の定義を簡単に拡張して、線だけではなく、三角形や正方形もサポートできます。
下の短いコードは、1つの可能な定義を示しています。

Type myObj
    objid As Integer
    Union
            myLine(1 To 2) As myPoint
        myTriangle(1 To 3) As myPoint
        mySquare(1 To 4) As myPoint
    End Union
    char As String * 1
End Type


objid 項目は、Union 定義に含まれているオブジェクトの型を示します。
すなわち、1は線を、2は三角形を、そして、3は正方形を示します。
定義は、単一のオブジェクトを定義するので、メモリ使用量を最大にするために、Union を使って、終点配列を囲みます。

オブジェクトを画面に表示するには、objid を調べて、次に、適切な終点配列定義の、Lbound と Ubound を使い、オブジェクトの型と一致する行数を、表示します。

更に、このプログラムを拡張できます。関数ポインタを型定義に加えて、それから、表示されるオブジェクトの型と一致する、表示ルーチンを書きます。
このテクニックを使うと、型定義に新しいオブジェクトを加えるプロセスを簡素化して、コードの有用性をさらに広げることができます。

例えば、立方体を描写しようとするなら、単に新しい配列を Union に追加して、立方体表示関数と、型の定義を追加します。
こうすると、数行のコード加えるだけで、立方体を表示できます。その一方で、元の機能性は完全に保持しています。


配列の初期化

Dim 命令文を使って、値で配列を初期化できます。他の組み込みデータ型や、型定義を初期化するのと同様の方法です。
下の短いコードは、1次元配列を使う構文の例です。

Dim aArray(1 To 5) As Integer => {1, 2, 3, 4, 5}


この短いコードは、5つの要素の整数の配列を、定義します。そして、要素を、{}で囲まれたリストに、設定します。
矢印演算子、=> は、Dim 命令文に従うリストを使って、配列を初期化するように、コンパイラに伝えます。

また、同じ方法で、多次元配列を定義できます。{}で囲んで、ブロックのデータを指定します。
下の短いコードの例を参照下さい。

Dim bArray(1 To 2, 1 To 5) As Integer => {{1, 2, 3, 4, 5},{6, 7, 8, 9, 10}}


この例では、最初のブロック {1, 2, 3, 4, 5} は、行 1 に対応しています。そして、2番目のブロック {6, 7, 8, 9, 10} は、行 2 に対応しています。
FreeBasic の配列は、行優先であることを覚えてください。それで、行は、列の前に指定されます。
この方法で配列を初期化するとき、指定した要素数が、配列に収まることを確認しなければなりません。


型の配列を初期化

簡単なデータ型の配列を初期化できるだけではなく、複合型でも配列を初期化できます。
下の短いコードは、型の要素として配列を含む、型配列の例です。

Type aType
    a As Integer
    b As Byte
    c(1 To 2) As String * 10
End Type

Dim As aType myType(1 To 2) => { (1234, 12, {"Hello", "World"}), (5678, 24, {"From", "Freebasic"})} 


波括弧 {} は、配列の初期化を示します。丸括弧は、型の初期化を示します。
型は、埋め込まれた配列を持つので、埋め込まれた配列にデータをロードするのに、波括弧 {} を使います。スタンドアロンの配列の場合と同じです。
埋め込まれた配列が多次元配列であれば、各行を { と } で包む必要があります。これも、スタンドアロンの配列の場合と同じです。


-exx コンパイラ・スイッチを使う

-exx コンパイラ・スイッチは、プログラムの中で、エラーと範囲のチェックを可能にします。
プログラムで、配列の領域の外に行くと、コンパイラは、プログラムの実行中に、"out of bounds" エラーを生成します。

これは、プログラムをデバッグして、配列に関連する問題を見つけるのに、大いに役立つでしょう。
-exx は、また、Null ポインタ代入を知らせるので、ポインタを使っているとき、非常に役に立ちます。

-exx を使うと、プログラムにかなりのコードが追加されます。
このため、プログラムが正しく機能したら、-exx スイッチ無しでプログラムをコンパイルします。

いっしょに学ぼう に戻る

最終、Sancho3によるレビュー(2018年2月06日)
←リンク元に戻る プログラム開発関連に戻る
ページ歴史:2018-02-11 11:25:36
日本語翻訳:WATANABE Makoto、原文著作者:WikiRick(Rick Clark aka rdc)

ホームページのトップに戻る

表示-非営利-継承