第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次元配列で書き換えてみましょう。
VB講義へ
VB講義基礎へ
vc++講義へ第1部へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)