これまで、配列、文字列と説明してきました。
基本制御文と配列があれば、様々なプログラムを組むことが可能なことが分かったと思います。
今回からは配列の続きとして二次元配列について説明します。
これまで配列と呼んで使ってきたのは「一次元配列」というものです。
宣言方法は、
int data[10];
といった方法で作ることが出来、イメージは↓の通りです。
data 0 1 2 3 4 5 6 7 8 9 +−+−+−+−+−+−+−+−+−+−+ | | | | | | | | | | | +−+−+−+−+−+−+−+−+−+−+
これに対して二次元配列は↓のように宣言します。
int data[4][10];
このように2つの添え字を使って宣言し、イメージは↓の通りです。
data 0 1 2 3 4 5 6 7 8 9 +−+−+−+−+−+−+−+−+−+−+ 0| | | | | | | | | | | +−+−+−+−+−+−+−+−+−+−+ 1| | | | | | | | | | | +−+−+−+−+−+−+−+−+−+−+ 2| | | | | | | | | | | +−+−+−+−+−+−+−+−+−+−+ 3| | | | | | | | | | | +−+−+−+−+−+−+−+−+−+−+
一次元配列を複数積み重ねた状態をイメージしてください。
最初の添え字が「縦方向」2番目の添え字が「横方向」を表します。
少し小さめの二次元配列で説明を続けます。
int data[2][3]; |
data 0 1 2 +−+−+−+ 0| | | | +−+−+−+ 1| | | | +−+−+−+
縦方向に2、横方向に3の合計6つの要素がある二次元配列です。
初期値としてデータを入れておくには↓のように宣言します。
int data[2][3] = { { 0, 1, 2 }, { 3, 4, 5 }, }; |
※最後のセミコロンを忘れないようにしてください。
この時のイメージを書きます。
data 0 1 2 +−+−+−+ 0|0|1|2| +−+−+−+ 1|3|4|5| +−+−+−+
例えば、「3」の入っている場所を指定する方法は、
data[1][0] |
となり、「2」が入っている場所は、
data[0][2] |
という具合に指定します。
縦方向を先に指定、横方向を次に指定という事をしっかりと覚えてください。
では、実際のプログラムを動かしてみましょう。
一次元配列と同じく、縦横の要素数は#defineで定義します。
名前は以下の通りとします。
縦方向 ROW 行 横方向 COL 列 ※COLUMN(カラム)の略
<sample program 090-01>
#include <stdio.h> #define ROW 2 #define COL 3 int main(void) { int data[ROW][COL] = { { 0, 1, 2 }, { 3, 4, 5 }, }; printf("data[1][0] = %d\n", data[1][0]); printf("data[0][2] = %d\n", data[0][2]); return 0; } |
<実行結果>
data[1][0] = 3 data[0][2] = 2 続行するには何かキーを押してください・・・
縦横の順番さえ間違えなければ、特に問題なく扱えると思います。
次に、二次元配列の中身を全て表示するプログラムを作ります。
よく使うプログラムになりますので、しっかりと考え方を身に付けてください。
int data[2][3] = { { 0, 1, 2 }, { 3, 4, 5 }, }; |
この二次元配列の中身を全て表示したいと思います。
まずは、添え字を付けた図で考えます。
data 0 1 2 +−+−+−+ 0|0|1|2| +−+−+−+ 1|3|4|5| +−+−+−+
全部で6つのデータがありますが、0から5まで順番に表示することを考えると
printf("%d\n", data[0][0]); printf("%d\n", data[0][1]); printf("%d\n", data[0][2]); printf("%d\n", data[1][0]); printf("%d\n", data[1][1]); printf("%d\n", data[1][2]); |
このようにprintfが6回必要になります。
しかし、添え字の並びを良く見てください。
前にこのような数値の変化を説明しましたが覚えていますか?
二重ループという考え方です。
※忘れたという方はここから復習してください。
基本的に二重ループの外側のループで縦方向を、内側のループで横方向の添え字を表すように作ります。
for (i = 0; i < ROW; i++) { for (j = 0; j < COL; j++) { } } |
この二重ループでのiとjの変化を書き出してみます。
まずは言葉で
iが0の時、jは0からCOL-1まで変化します。 jがCOLに達したら内側のループは終わりiが1増えます。 iが1の時、jは0からCOL-1まで変化します。 jがCOLに達したら内側のループは終わりiが1増えます。 iがROWに達したら外側のループは終わります。
次に数値で
i = 0 j = 0 i = 0 j = 1 i = 0 j = 2 i = 0 j = 3 ※ここで内側のループ終わり i = 1 j = 0 i = 1 j = 1 i = 1 j = 2 i = 1 j = 3 ※ここで内側のループ終わり i = 2 ※ここで外側のループ終わり
ループの終わりを省略して書くと
i = 0 j = 0 i = 0 j = 1 i = 0 j = 2 i = 1 j = 0 i = 1 j = 1 i = 1 j = 2
こうなります。
上に書いたprintf6回の添え字と比べてください。
一次元配列と繰り返しは切っても切れない関係だと説明しましたが、二次元配列と二重ループも同様の関係です。
では、プログラムを書いてみましょう。
<sample program 090-02>
#include <stdio.h> #define ROW 2 #define COL 3 int main(void) { int data[ROW][COL] = { { 0, 1, 2 }, { 3, 4, 5 }, }; int i; int j; for (i = 0; i < ROW; i++) { for (j = 0; j < COL; j++) { printf("%d\n", data[i][j]); } } return 0; } |
<実行結果>
0 1 2 3 4 5 続行するには何かキーを押してください・・・
これで、ループを使って二次元配列の中身を全て表示出来るようになりました。
ただ、イメージ的に
data 0 1 2 +−+−+−+ 0|0|1|2| +−+−+−+ 1|3|4|5| +−+−+−+
のように書きましたので、表示結果も同じようなイメージにしたいです。
毎回改行することをやめ、2まで表示した時に改行することで対応します。
2まで表示した時というのは、最初の1行目の表示が終わった時です。
1行目の表示が終わったタイミングとは、内側のループが終わった時になります。
これは皆さんにチャレンジしてもらいましょう。
考えて作ってください。
解答例です。
<sample program 090-03>
#include <stdio.h> #define ROW 2 #define COL 3 int main(void) { int data[ROW][COL] = { { 0, 1, 2 }, { 3, 4, 5 }, }; int i; int j; for (i = 0; i < ROW; i++) { for (j = 0; j < COL; j++) { printf("%d", data[i][j]); } printf("\n"); } return 0; } |
<実行結果>
012 345 続行するには何かキーを押してください・・・
何となくイメージ通りになりました。
罫線などは表示すると難しくなるため表示しません。
数字と数字の間隔を1文字分開けてやるともう少し見やすくなるかもしれません。
「%d」の後ろに半角空白を追加してみましょうか。
<sample program 090-04>
#include <stdio.h> #define ROW 2 #define COL 3 int main(void) { int data[ROW][COL] = { { 0, 1, 2 }, { 3, 4, 5 }, }; int i; int j; for (i = 0; i < ROW; i++) { for (j = 0; j < COL; j++) { printf("%d ", data[i][j]); } printf("\n"); } return 0; } |
<実行結果>
0 1 2 3 4 5 続行するには何かキーを押してください・・・
次回からは二次元配列を使ったプログラムを色々作っていきます。