c言語 2次元以上の多次元配列 これを見たら誰でもわかる!
どうも!ムバサです!
この記事ではC言語の2次元以上の多次元配列について徹底解説をしています!
この記事を読めば誰でも2次元配列についてわかるように使い方をソースコードと共に掲載しているので是非参考にしながら学習してみてください!
c言語 多次元配列とは?
多次元配列とは
2次元以上の配列。つまり1次元配列以外の配列のことを指します。
1次元配列については以下の記事にて詳しく解説しています!
1次元配列とは
「1x◯」の要素を持った配列です。イメージとしては配列を図に表した時に直線になる配列です。
掛け算の九九で言うところの「1の段」とか「2の段」ですね。
2次元配列とは
「◯x△」の要素を持った配列です。イメージとしては配列を図に表した時に平面になる配列です。
掛け算の九九そのものが2次元配列になります。
3次元配列とは
「◯x△x⬜︎」の要素を持った配列です。イメージとしては配列を図に表した時に立体になる配列です。
ルービックキューブの形をイメージしてください。まさにあんな感じです。
その他
4次元配列とか難しい配列もあります。
これらを踏まえて、二次元以上の配列のことを「多次元配列」って呼びます。「多数」の「次元」を持つ「配列」で「多次元配列」ということになります
1次元じゃない配列は多次元配列なんだなぁ〜って解釈で大丈夫です!
c言語 2次元配列の使い方
c言語 2次元配列の宣言・初期化
2次元配列の宣言と初期化はどうやるの?という疑問についてお答えします。
2次元配列は
データ型 配列名[行数][列数] = {{要素[0][0],要素[0][1],.......},{要素[1][0],要素[1][1],......}};
という形で宣言します。「{}」で要素全部を囲って、その中にさらに「{}」で行ごとに区切り、「,」で列ごとに区切っていきます。
変数の宣言と同時に初期化を行うサンプルを以下に示します。
普通の変数で int i=5; とやるのと同じイメージです。
次に要素1つずつに代入をして宣言と初期化を行う時のサンプルを以下に示します。
これを応用すると、scanf文を使ってキーボードから任意の値を代入することができます。以下に例を示します。
もちろん文字列型でも配列が使えます。書式は基本的に変わりませんが少し違ってきます。以下に例を示すので確認してみてください。
いやこれ1次元配列じゃね?と思った方いるかもしれませんが、ちゃんと2次元配列になっています。
文字列の配列というのは「sendai」という文字列を格納するのに1次元分利用してしまいます。
つまり複数の文字列を格納するには2次元配列を利用しているのです。
c言語 2次元配列のポインタ
2次元配列をポインタで使う場合には、2次元配列を分解して、1次元配列ごとにポインタを使い、それをまとめて使います。
c言語 2次元配列のポインタを扱う上で
ここで、2次元配列を使う上で便利な関数を紹介します。
固定の長さの配列ではなく、動的に要素をあり当てる際にはmalloc関数を使用します。
配列ではmalloc関数の引数に配列の要素数を指定して、必要なバイト数をを確保してもらいます。
ちなみにですが、プログラムの中でmalloc関数でメモリを確保した後にはfree関数というものを使ってメモリを解放してあげましょう。
メモリを解放しないと、プログラムが実行中そのメモリ領域が独占されてしまうため、他のプログラムに使用できなくなってしまいます。
malloc関数、free関数の使い方や詳しい解説については以下の記事を参照してください
ちなみに、malloc関数とfree関数では「stdlib.h」というヘッダーファイルをインクルードする必要があるので注意しましょう。
2次元配列として扱う方法
2次元配列として扱う場合には、各行のデータにアクセスするためのアドレスと、そのアドレスを保持するためのポインタが必要になります。
2次元配列を1次元配列ごとに分解してポインタで参照する感じですね。
イメージしやすいように図に表すとこんな感じになります
どのように使うのか?は以下にサンプルを示します。
このコードを実行した結果は以下のようになります。
このプログラムでは変数「m」で何列か、変数n「n」で何行か、ということを定義しています。
0から1ずつ増やしていくのをn行m列分出力するプログラムです。
free関数によってメモリを解放していないのは、このプログラムでしか使わないので、特に問題がないためです。
Arrayにアスタリスクが2つついているのは、ポインタのポインタという意味です。
これは変数を間接的に参照しているポインタ自身がどこかのアドレスに格納されているため、そのアドレスの場所を参照するものです。
ポインタのポインタに関しては今後詳しい記事を記述します
Array = malloc(sizeof(int *) * n);
というコードでn行分の領域を確保しています。
Arrayでは各行の先頭のアドレスが格納されているアドレスの先頭のアドレスを参照しています。複雑ですね。
int型のポインタとして利用するために「(int *)」でキャストします。
ポインタのポインタとして使うため、nの前に「*」をつけて合わせてあげます。
次に
Array[i] = malloc(sizeof(int) * m);
というコードで1行あたりm列分の領域を確保しています。
先ほど行分の領域を確保したことにより、「Array[i]」という書き方ができるようになります。
Array[i]では各行の先頭のアドレスを参照します。
ここまできて、「Array[i]」を先頭として、m列分の配列が使えますよ!ってことになります。
かなり複雑ですが実際にコードを動かしてみて、イメージを掴めればわかりやすくなると思います。
要点をまとめると「Array[i][j]」という配列の要素を使うために各列の先頭のアドレスが格納されている「Array[i]」というポインタを使います。
そして「Array[i]」というポインタがn個分作られて格納されているので、それを使うために「Array」というポインタのポインタを使うのです。
c言語 3次元以上の配列の使い方は?
c言語では配列の次元をいくらでも増やすことができます。
しかしながら大抵は2次元配列で足りてしまい、多くても3次元配列までしか使われないことがほとんどです。
(4次元配列を使った方がいい場合などもあるようですが。)
ということで、3次元配列の使い方です。
1次元配列から2次元配列になった時と同じように「[]」の数を一つ増やしてあげればOKです。簡単なサンプルを示します。
このようにして宣言、初期化を行います。2次元配列についての理解ができている方ならなんとなくわかりますよね。
2次元配列では「縦x横」のイメージになっていたと思いますが、3次元配列ではそこに高さが加わり、「縦x横x高さ」というイメージを持ってもらえるとわかりやすいです。
いくつもの2次元配列が高く重なり合っている状態のものが3次元配列ということになります。
まさにルービックキューブのような感じです。
まとめ
この記事では主に2次元配列についての説明を行いました。
2次元配列は1次元配列に比べてポインタでの扱いが非常に複雑になりますよね。
2次元配列は単に、1次元配列の集合である、ということが直感的に理解できれば扱い方もわかってくると思います。
2次元配列を使いこなすことができればc言語でのプログラミングの幅が大きく広がります。
この記事を参考に実際にプログラムを書いてみてわかるまで繰り返しましょう!
読んでくださってありがとうございました。
少しでもいいなと思った方は読者登録やTwitterのフォローお願いします!