第9講 ポインタの学習  
第5話 2次元配列とメモリーの関係
コード再掲

void f(){
   int i,j,a[4][4];
   for(i=0;i<4;i++){
     for(j=0;j<4;j++){
       a[i][j]=4*i+j+1;
     }
   }
   for(i=0;i<4;i++){
     for(j=0;j<4;j++){
       if(a[i][j]<10)cout<<a[i][j]<<" ";
       if(a[i][j]>=10)cout<<a[i][j]<<" ";
     }
     cout<<endl;
   }
}
void g(){
   int i,j,*a;
   a=(int *)malloc(64);
   for(i=0;i<16;i++){
     *(a+i)=i+1;
   }
   for(i=0;i<4;i++){
     for(j=0;j<4;j++){
       if(*(a+4*i+j)<10)cout<<*(a+4*i+j)<<" ";
       if(*(a+4*i+j)>=10)cout<<*(a+4*i+j)<<" ";
     }
     cout<<endl;
   }
}

つまり、2次元配列のa[i][j]とポインタの*(a+4*i+j)同じです。
この謎はメモリーと配列の関係を考えれば解けます。

例えば、
int b[2][3];
の場合データは次のよう2次元に並びます。

b[0][0]  b[0][1]  b[0][2] 
b[1][0]  b[1][1]  b[1][2] 

ですがメモリはどのように配置されているかと申しますと、

 アドレス 00000000  0000004  00000008  00000012  0000016  00000016 
配列  b[0][0]  b[0][1]  b[0][2]  b[1][0]  b[1][1]  b[1][2] 

と直線的に並んでいます。結局2次元配列とは本来的には、1次元データ(直線的データ)を見かけだけ2次元にしたものに過ぎません。
ですから、ポインタと次のように対応させることができます。

配列  b[0][0]  b[0][1]  b[0][2]  b[1][0]  b[1][1]  b[1][2] 
 ポインタ *a  *(a+1)  *(a+2)  *(a+3)  *(a+4)  *(a+5) 

と対応させることができます。また、この表からb[i][j]=*(a+3*i+j)であることもわかります。

配列  b[0][0]  b[0][1]  b[0][2]  b[1][0]  b[1][1]  b[1][2] 
 ポインタ *a(3*0+0 *(a+3*0+1 *(a+3*0+2 *(a+3*1+0 *(a+3*1+1 *(a+3*1+2

がわかります。ですから、2次元配列は1次元配列でも表現できます。

2次元 b[0][0]  b[0][1]  b[0][2]  b[1][0]  b[1][1]  b[1][2] 
 1次元 a[3*0+0)] a[3*0+1 a[3*0+2 a[3*1+0 a[3*1+1 a[3*1+2

つまり、b[i][j]=a[3*i+j]です。
さて、では皆さん4次および6次魔方陣作成プログラムを
ポインタで書き換えてみましょう。
また、同じく1次元配列で書き換えてみましょう。


第4話へ 第6話へ


戻る


VB講義へ
VB講義基礎へ

vc++講義へ第1部へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)