[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
配列は似た性質のデータをまとめて取り扱えるようにするデータ形式です。 配列の機能は、その昔の言語である FORTRAN , C言語 (私も使った言語ですが)等でも持っています。 ここまで配列の機能が残っているということは、それなりに使い勝手が良いのではないかと思います。 そこで今回は、配列の使い方について順を追って説明したいと思います。
■簡単な配列の宣言と使い方
以下のソースを見て下さい。 処理の前半は、配列を利用しない場合の合計処理を示しています。 配列が無い場合は、値を別々の変数に宣言して、それぞれを参照し合計を求めています。 配列を利用しないと非常に煩雑になってしまします。
処理の後半で配列を利用する場合を示しています。 配列の各要素に値を設定する部分は、ベタに記述していますが、合計を求めるところで 配列の処理らしさが現れています。 (この処理などは初歩の初歩なので特に難しくないと思います。)
Private Sub btnArray_Click(sender As Object, e As EventArgs) Handles btnArray.Click '===配列を利用しない場合の合計処理=== '各変数の宣言 Dim nVal1 As Integer Dim nVal2 As Integer Dim nVal3 As Integer Dim nVal4 As Integer Dim nVal5 As Integer '値の設定 nVal1 = 1 nVal2 = 10 nVal3 = 100 nVal4 = 1000 nVal5 = 10000 '値の合計 Dim nSum As Integer nSum = nVal1 + nVal2 + nVal3 + nVal4 + nVal5 Console.WriteLine("配列を利用しない場合の合計処理:{0}", nSum) '===配列を利用=== '配列宣言 Dim arr(5) As Integer '要素に値設定 arr(1) = 1 arr(2) = 10 arr(3) = 100 arr(4) = 1000 arr(5) = 10000 '指標宣言 Dim i As Integer '合計計算 nSum = 0 For i = 1 To 5 nSum = nSum + arr(i) Next Console.WriteLine("配列を利用した場合の合計処理:{0}", nSum) End Sub
実行結果がコンソールには以下様に表示されます。(当然合計値は同じ結果)
配列を利用しない場合の合計処理:11111 配列を利用した場合の合計処理:11111
■配列宣言の落とし穴
上記のソースでは配列宣言で Dim arr(5) As Integer と宣言しましたが、 領域としては指標が「1」~「5」まで確保されたかの様に感じますが、実は指標「0」の要素が存在します。
そこで上記のソースを以下の様に変更し実行してみます。
Private Sub btnArray_Click(sender As Object, e As EventArgs) Handles btnArray.Click '===配列を利用=== '配列宣言 Dim arr(5) As Integer '要素に値設定 arr(1) = 1 arr(2) = 10 arr(3) = 100 arr(4) = 1000 arr(5) = 10000 arr(0) = 10000 '指標「0」の要素 '指標宣言 Dim i As Integer '合計計算 nSum = 0 For i = 0 To 5 nSum = nSum + arr(i) Next Console.WriteLine("配列を利用した場合の合計処理:{0}", nSum) End Sub
配列を利用した場合の合計処理:21111
結果を見れば指標「0」の要素が存在することが分かります。
Dim arr(5) で5個の領域を宣言したつもりが指標「0」の要素が存在するため、 全体では6個の領域を宣言したことになります。
配列の開始が指標「0」と考えるのか、それとも指標「1」からとするのかで、プログラムの動作や組み方が変わってきます。 複数の人で組む場合にはなおさらで、どちらにするのかを決めておく必要があります。
配列の開始が指標「0」を使うのであれば、必要個数の1個少な目で配列宣言するのか、 それとも指標「1」ならば必要個数で配列宣言し、指標「0」の要素は未使用とするか、と言ったところです。
■配列の初期化
配列の宣言で一緒に初期化ができます。 配列の要素数を記述せずに、宣言のデータ型の後に、=(イコール) で繋ぎ {}(中括弧) で要素を ,(カンマ) で区切って記述します。
上記のソースを配列の初期化を行う様に変更します。
Private Sub btnArray_Click(sender As Object, e As EventArgs) Handles btnArray.Click '配列宣言(初期化) Dim arr() As Integer = {10000, 10000, 1000, 100, 10, 1} '指標宣言 Dim i As Integer '合計計算 Dim nSum As Integer nSum = 0 For i = 0 To 5 nSum = nSum + arr(i) Next Console.WriteLine("配列宣言(初期化)を利用した場合の合計処理:{0}", nSum) End Sub
このソース合計計算の For ループで「5」を直値(リテラル)で記述しています。 この場合は「5」であることが明らかなので問題は無いのですが、 配列の最終の指標が何か分からない時には UBound 等を用います。 以下に項目を新しくして説明します。
■配列の最終指標はUBound
UBound 関数は配列内の指定された次元における最も大きいインデックスを返します。
Public Function UBound(Array As System.Array, Optional Rank As Integer = 1) As Integer 引数: ・Array:任意のデータ型の配列です。 ある次元で最も大きいインデックスを探す対象となる配列です。 ・Rank :省略可能です。 Integer. 最も大きいインデックスが返される次元です。 1番目の次元の場合は「1」、2番目の次元の場合は「2」という形で指定します。 Rank を省略した場合、「1」が使用されます。 戻り値:Integer型 ・指定した次元に設定できるインデックスの最大値です。 ・Array に要素が 1 つしかない場合、UBound は 0 を返します。 ・Array に要素が存在しない場合 (長さ 0 の文字列の場合など)、UBound は -1 を返します。
以下の例では For ループの最終指標にこの UBound 関数を使っています。
尚、配列のプロパティのには現在の配列の大きさ(長さ)を返してくれる Length がありますのでそれを使っても同様です。 但し、 Length は個数なので「-1」する必要があります。
Private Sub btnArray_Click(sender As Object, e As EventArgs) Handles btnArray.Click '配列宣言(初期化) Dim arr() As Integer = {10000, 10000, 1000, 100, 10, 1} '指標宣言 Dim i As Integer '合計計算 Dim nSum As Integer = 0 '[Ubound]を使った最終指標 For i = 0 To UBound(arr) nSum = nSum + arr(i) Next Console.WriteLine("配列宣言(初期化)を利用した場合の合計処理:{0}", nSum) nSum = 0 '配列の大きさを返すプロパティ[Length]を使った最終指標 For i = 0 To arr.Length - 1 nSum = nSum + arr(i) Next Console.WriteLine("配列宣言(初期化)を利用した場合の合計処理:{0}", nSum) End Sub
■配列のサイズ変更(ReDim)
配列のサイズを変更するために ReDim 命令を使います。
以下のソースでは ReDim 命令で指標が「2」までのサイズに縮めています。 (合計の結果は「21000」を想定していますが...)
Private Sub btnArray_Click(sender As Object, e As EventArgs) Handles btnArray.Click '配列宣言(初期化:要素6個) Dim arr() As Integer = {10000, 10000, 1000, 100, 10, 1} '配列サイズ変更 ReDim arr(2) '合計計算 Dim nSum As Integer = 0 '[Ubound]を使った最終指標 For i As Integer = 0 To UBound(arr) nSum = nSum + arr(i) Next Console.WriteLine("配列をReDimでサイズ変更した場合の合計処理:{0}", nSum) End Sub
しかし結果は「0」となってしまいます。
配列をReDimでサイズ変更した場合の合計処理:0
これは ReDim 命令はサイズを変更した後で全ての要素をその配列のデータ型で初期化してしまうからです。 既に存在した要素を引き継ぐ場合には ReDim 命令で Preserve を指定します。
Private Sub btnArray_Click(sender As Object, e As EventArgs) Handles btnArray.Click '配列宣言(初期化:要素6個) Dim arr() As Integer = {10000, 10000, 1000, 100, 10, 1} '配列サイズ変更(Preserve指定) ReDim Preserve arr(2) '合計計算 Dim nSum As Integer = 0 '[Ubound]を使った最終指標 For i As Integer = 0 To UBound(arr) nSum = nSum + arr(i) Next Console.WriteLine("配列をReDimでサイズ変更した場合の合計処理:{0}", nSum) End Sub
結果は想定通り「21000」となりました。
配列をReDimでサイズ変更した場合の合計処理:21000
■配列のサイズ未指定での宣言
配列のサイズを指定せずに配列を宣言することができます。 この場合、配列は空の状態で存在し ReDim 命令でサイズを増やしてやらないと使用できません。 (空の状態の状態は Is Nothing で判定できます)
それでは、以下にInteger型配列をサイズ無しで宣言し、配列のサイズを順次拡張して中身が「0」~「9」となる 配列を作成する例を示します。
Private Sub btnArray_Click(sender As Object, e As EventArgs) Handles btnArray.Click '配列宣言 Dim arr() As Integer ' = Nothing はあった方がいいと思います '「0」~「9」の処理 For i As Integer = 0 To 9 If arr Is Nothing Then '最初は指標「0」 ReDim arr(0) arr(0) = i Else '次の指標 Dim idx As Integer = UBound(arr) + 1 'サイズ拡張 ReDim Preserve arr(idx) '要素設定 arr(idx) = i End If Next '配列の要素を文字列として連結 Dim str As String = "" For i As Integer = 0 To UBound(arr) If str <> "" Then str &= "," str &= arr(i) Next Console.WriteLine("配列:{0}", str) End Sub
配列:0,1,2,3,4,5,6,7,8,9
■配列のループ処理は For Each
上記に配列のループ処理の最終指標として UBound Array.Length を使いましたが、 指標に関係なく配列の要素を順次取得する方法が For Each … Next 処理です。 以下の実際のソースで直感的に分かると思います。For Each の後ろに配列の要素と同じデータ型の変数を記述し In の後ろに対象となる配列を記述します。
Private Sub btnArray_Click(sender As Object, e As EventArgs) Handles btnArray.Click '配列宣言(初期化) Dim arr() As Integer = {10000, 10000, 1000, 100, 10, 1} '要素宣言 Dim nEnt As Integer '合計計算 Dim nSum As Integer = 0 For Each nEnt In arr nSum += nEnt Next Console.WriteLine("For Each ... Nexを利用した場合の合計処理:{0}", nSum) End Sub
For Each ... Nexを利用した場合の合計処理:21111尚、要素用の変数を別で宣言しなくても以下の様にしても同様な結果となります。
Private Sub btnArray_Click(sender As Object, e As EventArgs) Handles btnArray.Click '配列宣言(初期化) Dim arr() As Integer = {10000, 10000, 1000, 100, 10, 1} '合計計算 Dim nSum As Integer = 0 For Each nEnt As Integer In arr nSum += nEnt Next Console.WriteLine("For Each ... Nexを利用した場合の合計処理:{0}", nSum) End Sub
関連する記事
⇒配列の使い方の注意点について(コピー, Clone)⇒配列の範囲指定によるコピー(Array.Copy, Skip, Take)
コメント