天国にいけるC言語入門 ヘキサ構造体 ver2.2126
2次元配列の配列変数a[0][0]は*a[0],**a、a[0][1]は*(a[0]+1),*(*a+1)、a[1][1]は*(a[1]+1),*(*(a+1)+1),*(a+1)[1]で表現できます
2次元配列の配列変数a[0][0]は*a[0],**a、a[0][1]は*(a[0]+1),*(*a+1)、a[1][1]は*(a[1]+1),*(*(a+1)+1),*(a+1)[1]で表現できます
今日は2次元配列の配列変数とその配列変数のアドレスが
どのように表されるかをじっくり考察してみよう
まずは次のプログラムをご覧ください
👇
#include <stdio.h>
int main() {
char a[3][3] = { "aa","bb","cc" };
printf("%c\n", a[0][0]);
printf("%c\n", a[0][1]);
printf("%c\n", a[0][2]);
printf("%c\n", a[1][0]);
printf("%c\n", a[1][1]);
printf("%c\n", a[1][2]);
printf("%c\n", a[2][0]);
printf("%c\n", a[2][1]);
printf("%c\n", a[2][2]);
printf("%p\n", a);
return 0;
}
ビルド実行結果
a
a
(空白)
b
b
(空白)
c
c
(空白)
008FFCB8
ソーラー「2次元配列宣言、初期化
char a[3][3] = { "aa","bb","cc" };
が実行されると
配列変数
a[0][0]
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]
a[2][0]
a[2][1]
a[2][2]
が生成され
配列変数
a[0][0]
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]
a[2][0]
a[2][1]
a[2][2]
に
文字データ
'a'
'a'
'\0'
'b'
'b'
'\0'
'c'
'c'
'\0'
が
a[0][0]='a';
a[0][1]='a';
a[0][2]='\0'
a[1][0]='b';
a[1][1]='b';
a[1][2]='\0';
a[2][0]='c';
a[2][1]='c';
a[2][2]='\0';
と
代入されます
さあて
いよいよだね
この2次元配列aの配列変数とその配列変数のアドレスが
どのように表されるかをじっくり考察してみよう
実は
このときの
a
は
char型の変数のアドレスを格納しているポインタ変数のアドレスを格納しているポインタ変数(ポインタのポインタ)なんです
命令文
printf("%p\n", a);
の実行結果が
008FFCB8
となっていることから
a
には
アドレス
008FFCB8
が格納されていることがわかります
ですから
aにアスタリスク演算子*を作用させた
*a
は
char型の変数のアドレスを格納しているポインタ変数となります
*aにアスタリスク演算子*を作用させた
**a
は
char型の変数
を表すことになります
そして
💖💖💖🌞🌞🌞アドレスが代入された🌞🌞🌞💖💖💖
💖💖💖🌞🌞🌞ポインタ変数a🌞🌞🌞💖💖💖
を用いれば
a[0]
a[1]
a[2]
を生成することができます
(アドレスが代入されていないポインタ変数aでは
配列変数
a[0]
a[1]
a[2]
を生成したとしても
配列変数
a[0]
a[1]
a[2]
は
配列変数として機能しません
なぜなら
ポインタ変数aにアドレスが代入されていないため
配列変数
a[0]
a[1]
a[2]
はどのアドレスのメモリにアクセスするか定められないからですね)
配列変数
a[0]
a[1]
a[2]
のアドレスを格納しているポインタ変数は
a
a+1
a+2
となるので
a[0]=*a
a[1]=*(a+1)
a[2]=*(a+2)
の関係が成り立ちます
さらに
a[0]
a[1]
a[2]
はポインタ変数なので
ポインタ変数a[0]
を用いれば
配列変数
a[0][0]
a[0][1]
a[0][2]
ポインタ変数a[1]
を用いれば
配列変数
a[1][0]
a[1][1]
a[1][2]
ポインタ変数a[2]
を用いれば
配列変数
a[2][0]
a[2][1]
a[2][2]
が生成されます
ポインタ変数a[0]
を用いて
配列変数
a[0][0]
a[0][1]
a[0][2]
を生成することができますが
a[0][0]のアドレスを格納しているポインタ変数はa[0]となります
そのことは
例えば
アドレスが代入されたポインタ変数b
を用いて
配列変数
b[0]
b[1]
b[2]
を生成することができますが
b[0]のアドレスを格納しているポインタ変数はb
となるのと一緒です
a[0][0]👈🌞a[0][0]のアドレスを格納しているポインタ変数はa[0]となります🌞
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]
a[2][0]
a[2][1]
a[2][2]
のアドレスを格納しているポインタ変数は
ポインタ変数であるa[0]に数値を足し合わせるポインタ演算を用いて
それぞれ
a[0]
a[0]+1
a[0]+2
a[1]
a[1]+1
a[1]+2
a[2]
a[2]+1
a[2]+2
とあらわされます
ですので
a[0][0]
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]
a[2][0]
a[2][1]
a[2][2]
のアドレスを格納しているポインタ変数
👇
a[0]
a[0]+1
a[0]+2
a[1]
a[1]+1
a[1]+2
a[2]
a[2]+1
a[2]+2
にアスタリスク演算子*を作用させた
*a[0]
*(a[0]+1)
*(a[0]+2)
*a[1]
*(a[1]+1)
*(a[1]+2)
*a[2]
*(a[2]+1)
*(a[2]+2)
は
配列変数
a[0][0]
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]
a[2][0]
a[2][1]
a[2][2]
を表すことになります
先程のプログラムでは
配列変数
a[0][0]
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]
a[2][0]
a[2][1]
a[2][2]
に
文字データ
'a'
'a'
'\0'
'b'
'b'
'\0'
'c'
'c'
'\0'
が
a[0][0]='a';
a[0][1]='a';
a[0][2]='\0'
a[1][0]='b';
a[1][1]='b';
a[1][2]='\0';
a[2][0]='c';
a[2][1]='c';
a[2][2]='\0';
と
代入されているわけです
a[0]
a[1]
a[2]
のアドレスを格納しているポインタ変数は
a
a+1
a+2
となるので
a[0]=*a
a[1]=*(a+1)
a[2]=*(a+2)
が成立します
このことを
配列変数
a[0][0]
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]
a[2][0]
a[2][1]
a[2][2]
をあらわす
*a[0]
*(a[0]+1)
*(a[0]+2)
*a[1]
*(a[1]+1)
*(a[1]+2)
*a[2]
*(a[2]+1)
*(a[2]+2)
に当てはめると
*a[0]
*(a[0]+1)
*(a[0]+2)
*a[1]
*(a[1]+1)
*(a[1]+2)
*a[2]
*(a[2]+1)
*(a[2]+2)
は
**a
*(*a+1)
*(*a+2)
**(a+1)
*(*(a+1)+1)
*(*(a+1)+2)
**(a+2)
*(*(a+2)+1)
*(*(a+2)+2)
と表されることになります
アレサ「こんなに
配列変数
a[0][0]
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]
a[2][0]
a[2][1]
a[2][2]
を
ポインタ変数aを用いてあらわす方法があるのですね」
ソーラー「さらに
他にも
配列変数
a[0][0]
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]
a[2][0]
a[2][1]
a[2][2]
を
ポインタ変数aを用いてあらわす方法があるんです
a
は
char型の変数のアドレスを格納しているポインタ変数のアドレスを格納しているポインタ変数(ポインタのポインタ)でした
ですから
aにアスタリスク演算子*を作用させた
*a
は
char型の変数のアドレスを格納しているポインタ変数となります
*aにアスタリスク演算子*を作用させた
**a
は
char型の変数
を表すことになります
そして
ポインタ変数aを用いれば
a[0]
a[1]
a[2]
を生成することができます
a[0]
a[1]
a[2]
のアドレスを格納しているポインタ変数は
a
a+1
a+2
となるので
a[0]=*a
a[1]=*(a+1)
a[2]=*(a+2)
となっています
a[0]
a[1]
a[2]
はポインタ変数なので
ポインタ変数a[0]
ポインタ変数a[1]
ポインタ変数a[2]
を用いれば
配列変数
a[0][0]
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]
a[2][0]
a[2][1]
a[2][2]
が生成されます
さらに
a[0]
a[1]
a[2]
はポインタ変数なので
*a
*(a+1)
*(a+2)
もポインタ変数ですね
ですから
ポインタ変数*a
を用いれば
配列変数
*a[0]
*a[1]
*a[2]
が生成され
ポインタ変数*(a+1)
を用いれば
配列変数
*(a+1)[0]
*(a+1)[1]
*(a+1)[2]
が生成され
ポインタ変数*(a+2)
を用いれば
配列変数
*(a+2)[0]
*(a+2)[1]
*(a+2)[2]
が生成されます
まとめると
配列変数
*a[0]
*a[1]
*a[2]
*(a+1)[0]
*(a+1)[1]
*(a+1)[2]
*(a+2)[0]
*(a+2)[1]
*(a+2)[2]
が生成されています
a[0]
a[1]
a[2]
も
*a
*(a+1)
*(a+2)
も全く同じポインタ変数なので
配列変数
a[0][0]
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]
a[2][0]
a[2][1]
a[2][2]
と
配列変数
*a[0]
*a[1]
*a[2]
*(a+1)[0]
*(a+1)[1]
*(a+1)[2]
*(a+2)[0]
*(a+2)[1]
*(a+2)[2]
は
全く同じポインタ変数となるね
配列変数
a[0][0]
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]
a[2][0]
a[2][1]
a[2][2]
を
配列変数
*a[0]
*a[1]
*a[2]
*(a+1)[0]
*(a+1)[1]
*(a+1)[2]
*(a+2)[0]
*(a+2)[1]
*(a+2)[2]
で表すことができました
*a[0]👈🌞a[0][0]に等しいですの a[0][0]のアドレスを格納しているポインタ変数はa[0]、*aとなります🌞
*a[1]
*a[2]
*(a+1)[0]
*(a+1)[1]
*(a+1)[2]
*(a+2)[0]
*(a+2)[1]
*(a+2)[2]
のアドレスを格納しているポインタ変数は
ポインタ変数である*aに数値を足し合わせるポインタ演算を用いて
*a
*a+1
*a+2
*(a+1)
*(a+1)+1
*(a+1)+2
*(a+2)
*(a+2)+1
*(a+2)+2
となります
ですので
*a[0]👈🌞a[0][0]に等しいですの a[0][0]のアドレスを格納しているポインタ変数はa[0]、*aとなります🌞
*a[1]
*a[2]
*(a+1)[0]
*(a+1)[1]
*(a+1)[2]
*(a+2)[0]
*(a+2)[1]
*(a+2)[2]
のアドレスを格納しているポインタ変数
👇
*a
*a+1
*a+2
*(a+1)
*(a+1)+1
*(a+1)+2
*(a+2)
*(a+2)+1
*(a+2)+2
にアスタリスク演算子*を作用させた
**a
*(*a+1)
*(*a+2)
**(a+1)
*(*(a+1)+1)
*(*(a+1)+2)
**(a+2)
*(*(a+2)+1)
*(*(a+2)+2)
は
配列変数
a[0][0]
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]
a[2][0]
a[2][1]
a[2][2]
を表すことになります」
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます