<Sample Code>

#include <stdio.h>
typedef struct num {
 int num1;
 int num2;
 int num3;
 int num4;
} Num;
int main() {
 Num number[3] = {
   { 1, 2, 3, 4 },
   { 5, 6, 7, 8 },
   { 9, 10, 11, 12 }
 };
 Num* pnumber = number;
 int k;
 for (k = 0; k < 3; ++k) {
  printf("%p:%d  ", &number[k].num1, number[k].num1);
  printf("%p:%d  ", &pnumber->num2, pnumber->num2);
  printf("%p:%d  ", &pnumber->num3, pnumber->num3);
  printf("%p:%d  ", &pnumber->num4, pnumber->num4);
  pnumber++;
  printf("\n");
 }
 printf("\n");
 int list[3][4] = {
   { 1, 2, 3, 4 },
   { 5, 6, 7, 8 },
   { 9, 10, 11, 12 }
 };
 int i,j;
 for (i = 0; i < 3; ++i) {
  for (j = 0; j < 4; ++j) {
   printf("%p:%d  ", &list[i][j], list[i][j]);
  }
  printf("\n");
 }
 int (*p)[4];
 p = list;
 //printf("%d  ", *p);
 printf("%p  ", *p);
 printf("%d  ", **p);
 printf("\n");

 int big,small;
 for(big=0;big<3;++big){
  for(small=0; small<4; ++small){
   printf("%p:%d  ", *(p+big)+small, *(*(p+big)+small));
  }
  printf("\n");
 }
 return 0;
}

 

 

<STEP1>

構造体と2次元配列の感覚

 

#include <stdio.h>

typedef struct num{

int num1;

int num2;

int num3;

int num4;

}Num;

int main(){

 

Num number[3]={

{1,2,3,4},

{5,6,7,8},

{9,10,11,12}

};

int j;

for(j=0;j<3;++j){

printf("%p:%d  ",&number->num1, number->num1);  //構造体の型にアクセスして、その中のメンバにアロー演算子
printf("%p:%d  ",&number->num2, number->num2);   //構造体の型は、行を表す
printf("%p:%d  ",&number->num3, number->num3);  //つまり、行にアクセスして、次にその中身にアクセスしている感覚
printf("%p:%d  ",&number->num4, number->num4);
number++;

printf("\n");

}

 

printf("\n");

 

int list[3][4]={

{1,2,3,4},

{5,6,7,8},

{9,10,11,12}

};

int i;

for(i=0;i<3;++i){

for(int j=0;j<4;++j){

printf("%p:%d\t", &list[i][j], list[i][j]);

}

printf("\n");}

 

return 0;

}

 

構造体と2次元配列は構造が似ていると以前話をしましたね。

構造体は構造体の配列を作る際、構造体ごとに大きな箱を作って、その箱から中の箱にアクセスする感覚を今まで共有して来ました。

したがって、構造体の場合、感覚値として

「行全体にアクセスする」→「行のなかのカラム(セル)にアクセスする」の順番で値を参照しています。

 

2次元配列も同じ感覚です。

 

 

<STEP2>

#include <stdio.h>

int main(){

int list[3][4]={

{1,2,3,4},

{5,6,7,8},

{9,10,11,12}

};

int i;

for(i=0;i<3;++i){

for(int j=0;j<4;++j){

printf("%p:%d  ", &list[i][j], list[i][j]);

}

printf("\n");

}

printf("\n");

 

int (*p)[4];

p = list;

printf("%d", *p);  //*pでは行にしかアクセスできないので値を取れない

printf("%d", *p[0]);

printf("%d", **p);

return 0;

}

 

 

 

<STEP3>

#include <stdio.h>

int main(){

int list[3][4]={

{1,2,3,4},

{5,6,7,8},

{9,10,11,12}

};

int i;

for(i=0;i<3;++i){

for(int j=0;j<4;++j){

printf("%p:%d  ", &list[i][j], list[i][j]);

}

printf("\n");

}

printf("\n");

 

int (*p)[4];

p = list;

 

int t;

for(t=0; t<3; ++t){

printf("%p:%d  ", p,*p[0]);

p++;

printf("\n");

}

printf("\n");

 

//以下、上と同じ意味

int j;

p = list;

for(int j=0; j<3; ++j){

printf("%p:%d  ", p+j,*(p+j)[0]);

printf("\n");

}

return 0;

}

 

 

<STEP4>

#include <stdio.h>

int main(){

int list[3][4]={

{1,2,3,4},

{5,6,7,8},

{9,10,11,12}

};

int i;

for(i=0;i<3;++i){

for(int j=0;j<4;++j){

printf("%p:%d  ", &list[i][j], list[i][j]);

}

printf("\n");

}

printf("\n");

 

int (*p)[4];

p = list;

 

int t,s;

for(t=0; t<3; ++t){

for(s=0; s<4; ++s){

printf("%p:%d  ", (*p)+s,(*p)[s]); //*p[s]としたらエラー

}

printf("\n");

p++;

}

printf("\n");

 

//以下、上と同じ

int j,k;

p = list;

for(j=0; j<3; ++j){

for(k=0; k<4; ++k){

printf("%p:%d  ", *(p+j)+k,(*(p+j))[k]);  //*(p+j)[k]としたらエラー

}

printf("\n");

}

return 0;

}

 

 

<STEP5>

#include <stdio.h>

int main(){

int list[3][4]={

{1,2,3,4},

{5,6,7,8},

{9,10,11,12}

};

int i;

for(i=0;i<3;++i){

for(int j=0;j<4;++j){

printf("%p:%d  ", &list[i][j], list[i][j]);

}

printf("\n");

}

printf("\n");

 

int (*p)[4];

p = list;

 

int t,s;

for(t=0; t<3; ++t){

for(s=0; s<4; ++s){

printf("%p:%d  ", *(p+t)+s,*(*(p+t)+s)); //*p[s]としたらエラー

}

printf("\n");

}

return 0;

}