[C]多次元配列にアクセスする3つの方法 - わさっき
について,変数宣言が可能であることと,それぞれのサイズを確認するコードを書いてみました.
手元の処理系では,intとポインタのサイズが同じなので,区別するため,Tという型を作り,その2次元配列を参照するようにしました.
#include <stdio.h> #define printf_d(x) (printf(#x " = %d\n", x)) typedef struct T_dummy { char A[123]; } T; int main(void) { /* 2次元配列 */ T a[2][2]; /* 配列のポインタ */ T (*b_1)[2] = a; /* ポインタの配列 */ T *b_2[2] = {a[0], a[1]}; /* 1次元配列 */ T *b_3_1 = &a[0][0]; T *b_3_2 = a[0]; T *b_3_3 = (T *)a; printf_d(sizeof(T)); printf_d(sizeof(void *)); printf_d(sizeof(b_1)); printf_d(sizeof(b_1[0])); printf_d(sizeof(b_1[0][0])); printf_d(sizeof(b_2)); printf_d(sizeof(b_2[0])); printf_d(sizeof(b_2[0][0])); printf_d(sizeof(b_3_1)); printf_d(sizeof(b_3_1[0])); printf_d(sizeof(b_3_2)); printf_d(sizeof(b_3_2[0])); printf_d(sizeof(b_3_3)); printf_d(sizeof(b_3_3[0])); return 0; }
実行結果は以下の通り.
sizeof(T) = 123 sizeof(void *) = 4 sizeof(b_1) = 4 sizeof(b_1[0]) = 246 sizeof(b_1[0][0]) = 123 sizeof(b_2) = 8 sizeof(b_2[0]) = 4 sizeof(b_2[0][0]) = 123 sizeof(b_3_1) = 4 sizeof(b_3_1[0]) = 123 sizeof(b_3_2) = 4 sizeof(b_3_2[0]) = 123 sizeof(b_3_3) = 4 sizeof(b_3_3[0]) = 123
前に作った表と合致します.「sizeof(b_1[0]) = 246」は,b_1[0]がT[2]型(配列型)であることを裏付けています.
2次元配列で連想するもの: ザナドゥのタワー
プログラムを実行するだけではつまらないので,昔話を.
ザナドゥというテレビゲームがあって,その中のタワーの部屋は,8×8の2次元配列で表現できる構造になっていました.
部屋の上下左右に,通路があれば,移動できるのですが,そこで注意するのは,2次元配列で考えたときの右端,つまり座標でいうと(7,y)のときに(0オリジンとします),右に移動すると,(0,y)ではなく(0,y+1)の部屋に移っていたということです.
2次元配列での上端・下端をまたぐ移動については,特にこのようなずれがなかったことから,タワーの部屋は,計算機内部では要素数64の1次元配列で構成されていて,移動前の部屋位置をi,移動後をi_afterとすると,
- i_after = (i + delta) & 0x3f;
という代入で表現でき,ここの delta は,上下左右の移動に対してそれぞれ-8,8,-1,1,になっていたんだろうなと推測します.