パワサカお問い合わせホームプログラミングC言語C言語で2次元データをいろいろな方法で扱ってみる(二次元配列・ポインタのポインタなど)2019年8月15日SHAREツイートシェアはてブLINEPocketプログラミングをしていると二次元データを扱いたくなる時ってどうしても出てくると思います。画像データ(特にモノクロ画像)を扱ったり、統計を取ったりする時に二次元データが扱えると便利です。C言語では二次元データを扱う方法はたくさんあります。ポインタの配列」「ポインタのポインタ」および「一次元データを二次元配列として扱う」方法について解説していきます。配列とポインタの違いもイメージしやすいと思いますのでよろしければ是非読んでみてください。知識がある前提の解説になっていますので、ポインタについての理解に自信がない方はまず先に下のポインタ解説のページを読んでいただけると、理解しやすくなると思います。データとして真っ先に思い浮かぶのはこの二次元配列だと思います。二次元配列とは二次元配列とは配列自体を配列の要素としてもつ配列です。イメージとしては、縦方向と横方向にデータ格納領域が広がる配列として考えると良いと思います。二次元配列の場合、変数宣言を行うだけで二次元データを作成することが可能です。配列名(変数名)の後ろに配列のサイズを二方向分、つまりサイズを二つ指定することで二次元配列の変数宣言を行うことが可能です。array_2d[3][2];二次元配列の場合、この変数宣言を行うだけで、指定したサイズ分のデータを格納するためのメモリが確保されます。このメモリへのデータの格納やこのメモリからのデータの取得を行うことで、様々なアプリやプログラムを作成することが可能です。二次元配列の各要素へのアクセス二次元配列で配列の要素にアクセス(値の取得や値の代入)するためにはインデックス(添字)を二つ指定します。要素にアクセスすることが可能です。二次元配列を用いたプログラムの一例は下記のようになります。続いてポインタの配列を用いた2次元データの扱い方について解説します。ポインタの配列とはポインタの配列とはポインタを要素としてもつ配列のことです。二次元配列との大きな違いは下記の通りです。二次元配列:変数宣言で二次元データがメモリ上に作成されるポインタの配列:変数宣言でポインタ格納用の配列のみメモリ上に作成されるつまり、ポインタの配列で変数宣言でメモリ上に確保されるメモリは、アドレスを格納するためのメモリだけで、値やデータなどは格納するためのものではありません。したがって、ポインタの配列の場合は変数宣言だけでなく、プログラム中で値やデータを格納するためのメモリを動的確保に確保し、そのメモリを配列に格納されたポインタで指してやる必要があります。具体的に見ていきましょう。ポインタの配列の変数宣言は下記のようにポインタの変数名の後に配列のサイズを指定して行います。サイズとしては二次元データの縦方向のサイズを指定しましょう。*p_array[3];変数宣言直後のポインタの配列のメモリ上の様子を図示すると下のようになります。ポインタを格納する配列が存在するだけですね。ただの一次元データです。配列の中に格納されているポインタには不定値が格納されているのでどこを指しているか分からない状態になります。関数を用いてメモリの確保を行い、そのメモリをポインタで指します。変数宣言時にポインタ自体は配列サイズ分存在していますので、下記のようにループしながら各々ポインタがメモリを指すようにします。関数の引数には確保するメモリのサイズをバイト単位で指定します。指定していますので、下記のように配列の変数宣言を行なった時と同様のメモリが確保されることになります。array[2];そして、配列に格納されたそれぞれのポインタがループ内で確保したメモリを指している状態になります。データが飛び飛びなのであまり実感できないかもしれませんが、この状態でこれらのデータを二次元データとして扱うことが可能です。したメモリは解放しないとメモリリークになってしまいます。長時間稼働しているようなアプリやプログラムだと、メモリリークがたくさん起こると途中で動作できなくなってしまいます。free(p_array[i]);}ポインタの配列の各要素へのアクセスポインタの配列の各要素へのアクセスは二次元配列と全く同じ方法で行うことが可能です。インデックスを二つ指定すれば良いです。先頭アクセスし、100を格納することができます。要素にアクセスする時の様子を図示すると下のようになります。要素にアクセス時の様子を図示すると下のようになります。メモリ的にはそれぞれが離れていますがプログラム上では二次元配列と同じようにして扱うことが可能です。イメージ的には下の図のように考えると良いと思います。プログラム例ポインタの配列を用いたプログラムの一例は下記のようになります。0;}スポンサーリンクポインタのポインタ続いてポインタのポインタを用いた2次元データの扱い方に解説します。ポインタのポインタとはポインタのポインタとはポインタを指すポインタのことです。ダブルポインタとも呼ばれます。二次元配列およびポインタの配列とポインタのポインタとの大きな違いは下記の通りです。関数を用いてデータ格納用のメモリを確保する必要があります。ポインタのポインタ変数の場合、指すことができるのはポインタのみです。変数を2段階的に使用することで二次元データの作成を行うことになります。確保してその先頭アドレスをポインタのポインタ変数に指させます。確保し、その先頭アドレスを一段階目に確保したメモリに格納します(つまり確保したメモリの先頭アドレスを指させます)。関数で指定するメモリサイズですが、一段階目で指定したサイズが二次元データにおける縦方向のサイズ、二段階目で指定したサイズが二次元データにおける横方向のサイズと捉えることができます。サイズの二次元データとして扱うことができるというわけです。次はプログラムを見ながら具体的に解説していきます。ポインタのポインタの変数宣言は下記のように、変数名の前に「**」を記述します。**dptr;変数宣言直後のメモリ上の様子を図示すると下のようになります。ポインタのポインタ変数が一つのみ存在するだけです。関数を用いてメモリの確保を行い、そのメモリをポインタで指します。二次元データの縦方向のサイズ」を指定します。関数を積極的に使うと良いと思います。二次元データの縦方向のサイズ」分のメモリが確保され、ポインタのポインタがそのメモリの先頭を指すことになります。型のサイズ3の配列同様に扱うことが可能です。関数を使用してメモリの確保を行います。次は実際にデータを格納するためのメモリ領域の確保です。ここはポインタの配列の時と同様ですね。関数の戻り値であるアドレスを格納することです。これにより下記のようにメモリが確保され、各々のポインタがそれぞれ異なるメモリを指すことになります。解放してあげましょう。二段階的に行う必要があります。free(dptr[i]);}続いてポインタのポインタの指す先の解放を行えばオーケーです。free(dptr);ポインタのポインタの各要素へのアクセスポインタのポインタの各要素へのアクセスは前述した二次元配列およびポインタの配列と全く同じ方法で行うことが可能であり、インデックスを二つ指定すれば良いだけです。アクセスし、100を格納する処理が行われます。こちらもポインタの配列同様に各メモリ領域は飛び飛びですが、2次元配列同様に連続した領域のイメージを持って扱うことが可能です。プログラム例ポインタのポインタを用いたプログラムの一例は下記のようになります。0;}一次元データここまでは二次元データを作成してそれをそのまま二次元データとして扱う方法について解説してきました。実は一次元データでも、二次元データとして捉えて扱うことで二次元データを扱うことが可能です。一次元データを二次元データとして扱う考え方メモリ上に確保するのは一次元データです。用いてでもどちらでも問題ありません(このページでは配列を用いて解説します)。自分で制御しながらデータを扱うことで二次元データのように扱います。array[6];サイズ6の一次元配列分のメモリがメモリ上に確保されることになります。縦方向にサイズ3、横方向にサイズ2の二次元データとして考える場合、下の図のように青部分は一行目のデータ、緑部分は二行目のデータ、オレンジ部分は3行目のデータとして自分で制御することで元々は一次元のデータを二次元データのように扱うことができます。一次元配列による一次元データの作り方これはもはや説明不要かもしれませんが一応。下記のように変数宣言することでサイズ6の一次元データをメモリ上に作成することができます。array[6];一次元データを二次元データとして扱った時の各要素へのアクセス方法この方法ではこのアクセス方法がポイントになります。m)座標へのアクセスは下記により行うことができます。イメージ的には下の図のようになります。一次元配列を用いたプログラムの一例は下記のようになります。0;}>/code>まとめこのページでは、2次元データを2次元配列、ポインタの配列、ポインタのポインタで扱う方法および、一次元データを二次元データとして扱う方法について解説しました。とっつきやすいのは二次元配列ですかね。入力されるデータの縦サイズ・横サイズが変わるようなプログラムを作成する場合は、動的にサイズを指定できるポインタのポインタの方が省メモリなプログラムを作成することはできると思います。個人的には一次元データを二次元データとして扱う方法が一番使いやすいですね。画像処理のページなんかも公開していますが、全てこちらの方法で画像を扱うプログラムを紹介しています。慣れてくるとこの方法が一番使いやすいと思います。ポインタの配列が一番使わないかなぁ...。コメントをキャンセルメールアドレスが公開されることはありません。*サイト前の記事C言語でハノイの塔の解法プログラムを実装!次の記事C言語で二分探索木(木構造・ツリー構造)をプログラミングプライバシーポリシーだえうホームページのプライバシーポリシー・免責事項についてはこちらに記載しております。