天国にいけるC言語入門 ヘキサ構造体 ver2.2126
char (*a)[3];により生成されるポインタ変数aにはchar b[😊][3]:より生成される先頭の配列変数のアドレスを格納するポインタ変数*bのアドレスを格納するポインタ変数bを代入できます
char (*a)[3];により生成されるポインタ変数aにはchar b[😊][3]:より生成される先頭の配列変数のアドレスを格納するポインタ変数*bのアドレスを格納するポインタ変数bを代入できます
ソーラー「
char (*a)[3];により生成されるchar (*)[3]型のポインタ変数aには
2次元配列宣言
char b[😊][3];
👆ここが[3]になっているのがポイントです
により生成される
2次元配列b[😊][3]タイプの先頭の配列変数b[0][0]のアドレスを格納しているポインタ変数*bのアドレスを格納しているポインタ変数bを
a=b;
のように
代入することができます
(😊マークには1,2,3,4,5,6・・・・などの数値を代入することができます)
たとえば
😊マークに2を代入すると
今の説明文は
char (*a)[3];により生成されるchar (*)[3]型のポインタ変数aには
2次元配列宣言
char b[2][3];
👆ここが[3]になっているのがポイントです
により生成される
2次元配列b[2][3]タイプの先頭の配列変数b[0][0]のアドレスを格納しているポインタ変数*bのアドレスを格納しているポインタ変数bを
a=b;
のように
代入することができます!
となります
(⋈◍>◡<◍)。✧♡
2次元配列b[2][3]タイプの配列bのアドレスを格納しているポインタ変数は
b
と記述する場合もありますが
先のエピソードでもみてきたように
正確には
2次元配列b[2][3]の先頭の配列変数b[0][0]のアドレスを格納しているポインタ変数b*のアドレスを格納しているポインタ変数が
b
となります
くわしくは後のエピソードで😊
(⋈◍>◡<◍)。✧♡
solarplexuss「
char (*a)[3];により生成されるchar (*)[3]型のポインタ変数aには
2次元配列宣言
char b[😊][3];
👆ここが[3]になっているのがポイントです
により生成される
2次元配列b[😊][3]タイプの先頭の配列変数b[0][0]のアドレスを格納しているポインタ変数*bのアドレスを格納しているポインタ変数bを
a=b;
のように
代入することができたとして・・・
いったい どのような使い道がこのポインタ変数に
あるのかな?」
アレサ「うぅぅ~んんん
わからないです・・・」
ソーラー「
以下の説明では
😊マークに2を代入しています
実は
aのchar (*)[3]型のポインタ変数宣言
char (*a)[3];
により生成されるchar (*)[3]型のポインタ変数aに
char型の2次元配列宣言,初期化
char b[2][3]={"aa","bb"};
により生成される
char型の2次元配列b[2][3]タイプの先頭の配列変数b[0][0]のアドレスを格納しているポインタ変数*bのアドレスを格納しているポインタ変数bを
a=b;
のように
代入すると
2次元配列b[2][3]タイプの配列b
と全く同じタイプの
2次元配列a[2][3]タイプの配列a
が生成されます
2次元配列a[2][3]タイプの配列変数
a[0][0]
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]
を用いて
2次元配列b[2][3]タイプの配列変数
b[0][0]
b[0][1]
b[0][2]
b[1][0]
b[1][1]
b[1][2]
がアクセスしているメモリに
アクセスすることができるようになります」
solarplexuss「ど~いうことぉ?
配列変数
a[0][0]
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]
と
配列変数
b[0][0]
b[0][1]
b[0][2]
b[1][0]
b[1][1]
b[1][2]
は同じメモリにアクセスする配列変数だということ?」
ソーラー「そうなんです あたり!
2次元配列b[2][3]タイプの配列b
の配列変数
b[0][0]
b[0][1]
b[0][2]
b[1][0]
b[1][1]
b[1][2]
には
文字データ
'a'
'a'
'\0'
'b'
'b'
'\0'
が
b[0][0]='a';
b[0][1]='a';
b[0][2]='\0';
b[1][0]='b';
b[1][1]='b';
b[1][2]='\0';
のように代入されていますが
a=b;
の実行により
2次元配列a[2][3]タイプの配列a
の配列変数
a[0][0]
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]
にも
文字データ
'a'
'a'
'\0'
'b'
'b'
'\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[0][0]
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]
と
配列変数
b[0][0]
b[0][1]
b[0][2]
b[1][0]
b[1][1]
b[1][2]
は同じメモリにアクセスする配列変数なんです」
そのことを示すプログラムはこちらです
👇
#include <stdio.h>
int main(void) {
char b[2][3] = { "aa","bb" };
printf("%c\n", b[0][0]);
printf("%c\n", b[0][1]);
printf("%c\n", b[0][2]);
printf("%c\n", b[1][0]);
printf("%c\n", b[1][1]);
printf("%c\n", b[1][2]);
printf("%p\n", &b[0][0]);
printf("%p\n", &b[0][1]);
printf("%p\n", &b[0][2]);
printf("%p\n", &b[1][0]);
printf("%p\n", &b[1][1]);
printf("%p\n", &b[1][2]);
char(*a)[3];
a = b;
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("%s\n", a);
printf("%p\n", &a[0][0]);
printf("%p\n", &a[0][1]);
printf("%p\n", &a[0][2]);
printf("%p\n", &a[1][0]);
printf("%p\n", &a[1][1]);
printf("%p\n", &a[1][2]);
return 0;
}
ビルド実行結果
a
a
(空白)
b
b
(空白)
00FAEC04
00FAEC05
00FAEC06
00FAEC07
00FAEC08
00FAEC09
a
a
(空白)
b
b
(空白)
aa
00FAEC04
00FAEC05
00FAEC06
00FAEC07
00FAEC08
00FAEC09
ソーラー「
配列変数
a[0][0]
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]
と
配列変数
b[0][0]
b[0][1]
b[0][2]
b[1][0]
b[1][1]
b[1][2]
は同じメモリにアクセスする配列変数で
文字データ
'a'
'a'
'\0'
'b'
'b'
'\0'
をあらわしているのがわかりますね」
solarplexuss「な、なんと
これって
すごいことじゃない?
char型の2次元配列bの
配列変数がアクセスしているメモリに格納されているデータに
同じタイプの
別の2次元配列aの配列変数を用いてアクセスできている!
しかも
printf("%s\n", a);
の実行により
aa
まで表示されちゃって、まあ」
アレサ「うふ」
solarplexuss「
今までの知識では
bのchar型の2次元配列宣言、初期化
char b[2][3]={"aa","bb"};
と
aのchar型の2次元配列宣言
char a[2][3];
を実行して
a=b;
を実行することにより
2次元配列b[2][3]タイプの配列b
の配列変数
b[0][0]
b[0][1]
b[0][2]
b[1][0]
b[1][1]
b[1][2]
に格納されている文字データ
'a'
'a'
'\0'
'b'
'b'
'\0'
を
2次元配列a[2][3]タイプの配列a
の配列変数
a[0][0]
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]
に代入することはできなかった
つまり
配列bの配列変数に格納されているデータを
a=b;
を実行することにより
別の配列aの配列変数に代入することはできなかった
それが
2次元配列b[2][3]タイプの配列b
の配列変数
b[0][0]
b[0][1]
b[0][2]
b[1][0]
b[1][1]
b[1][2]
のアクセスしているメモリに
直接
別の配列変数
a[0][0]
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]
を用いてアクセスできるなんて・・・」
ソーラー「そうなんです
もちろん
char型でなくint型でも
つまり
👇
int (*a)[3];により生成されるポインタ変数aには
2次元配列宣言int b[😊][3];
により生成される
int型の2次元配列b[😊][3]タイプの先頭の配列変数b[0][0]のアドレスを格納しているポインタ変数b*のアドレスを格納しているポインタ変数bを
a=b;
のように
代入することができます
たとえば
int(*a)[3];により生成されるポインタ変数aに
int型の2次元配列宣言,初期化
int b[2][3]={{1,2,3},{4,5,6}};
により生成される
int型の2次元配列b[2][3]タイプの先頭の配列変数b[0][0]のアドレスを格納しているポインタ変数b*のアドレスを格納しているポインタ変数bを
a=b;
のように
代入すると
2次元配列b[2][3]タイプの配列b
と全く同じタイプの
2次元配列a[2][3]タイプの配列a
が生成されます
そして
このとき
2次元配列b[2][3]タイプの配列b
の配列変数
b[0][0]
b[0][1]
b[0][2]
b[1][0]
b[1][1]
b[1][2]
には
数値データ
1
2
3
4
5
6
が
b[0][0]=1;
b[0][1]=2;
b[0][2]=3;
b[1][0]=4;
b[1][1]=5;
b[1][2]=6;
と代入されていますが
a=b;
の実行により
配列変数
a[0][0]
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]
も
2次元配列b[2][3]タイプの配列b
の配列変数
b[0][0]
b[0][1]
b[0][2]
b[1][0]
b[1][1]
b[1][2]
アクセスしているメモリにアクセスできるようになり
配列変数
a[0][0]
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]
は
数値データ
1
2
3
4
5
6
を
あらわすことになります
そのことを示すプログラムはこちらです
👇
#include <stdio.h>
int main(void) {
int b[2][3] = { { 1,2,3 },{ 4,5,6 } };
printf("%d\n", b[0][0]);
printf("%d\n", b[0][1]);
printf("%d\n", b[0][2]);
printf("%d\n", b[1][0]);
printf("%d\n", b[1][1]);
printf("%d\n", b[1][2]);
printf("%p\n", &b[0][0]);
printf("%p\n", &b[0][1]);
printf("%p\n", &b[0][2]);
printf("%p\n", &b[1][0]);
printf("%p\n", &b[1][1]);
printf("%p\n", &b[1][2]);
int(*a)[3];
a = b;
printf("%d\n", a[0][0]);
printf("%d\n", a[0][1]);
printf("%d\n", a[0][2]);
printf("%d\n", a[1][0]);
printf("%d\n", a[1][1]);
printf("%d\n", a[1][2]);
printf("%p\n", &a[0][0]);
printf("%p\n", &a[0][1]);
printf("%p\n", &a[0][2]);
printf("%p\n", &a[1][0]);
printf("%p\n", &a[1][1]);
printf("%p\n", &a[1][2]);
return 0;
}
ビルド実行結果
1
2
3
4
5
6
00AFF6E4
00AFF6E8
00AFF6EC
00AFF6F0
00AFF6F4
00AFF6F8
1
2
3
4
5
6
00AFF6E4
00AFF6E8
00AFF6EC
00AFF6F0
00AFF6F4
00AFF6F8
アレサ「
2次元配列b[2][3]
の配列変数
b[0][0]
b[0][1]
b[0][2]
b[1][0]
b[1][1]
b[1][2]
と
配列変数
a[0][0]
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]
は
同じアドレス番号
00AFF6E4
00AFF6E8
00AFF6EC
00AFF6F0
00AFF6F4
00AFF6F8
のメモリにアクセスしているのですね
そして
配列変数
a[0][0]
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]
も
1
2
3
4
5
6
を
あらわすことになったのですね
🌞 🌞 🌞 🌞 🌞 🌞
ここで😊おまけ😊です
🌞 🌞 🌞 🌞 🌞 🌞
int b[2][3] = { { 1,2,3 },{ 4,5,6 } };
int(*a)[3];
a = b;
の実行により
int型の2次元配列aの配列変数は
int型の2次元配列bの配列変数のアクセスしているメモリに
アクセスできるようになりましたね
このとき
int型の2次元配列bの先頭の配列変数
b[0][0]のアドレスを格納しているポインタ変数は
b
ではありません
int型の2次元配列bの先頭の配列変数
b[0][0]のアドレスを格納しているポインタ変数は
*b
です
同様に
int型の2次元配列aの先頭の配列変数
a[0][0]のアドレスを格納しているポインタ変数は
a
ではありません
int型の2次元配列aの先頭の配列変数
a[0][0]のアドレスを格納しているポインタ変数は
*a
です
ですので
int型の2次元配列aの先頭の配列変数
a[0][0]に格納されているデータは
*a
にアスタリスク演算子を用いた
**a
であらわされることになります
そのことを示すプログラムはこちらです
👇
#include <stdio.h>
int main(void) {
int b[2][3] = { { 1,2,3 },{ 4,5,6 } };
printf("%d\n", b[0][0]);
printf("%d\n", b[0][1]);
printf("%d\n", b[0][2]);
printf("%d\n", b[1][0]);
printf("%d\n", b[1][1]);
printf("%d\n", b[1][2]);
int(*a)[3];
a = b;
printf("%d\n", a[0][0]);//👈ここです
printf("%d\n", a[0][1]);
printf("%d\n", a[0][2]);
printf("%d\n", a[1][0]);
printf("%d\n", a[1][1]);
printf("%d\n", a[1][2]);
printf("%d\n", **a);//👈ここです
printf("%d\n", a[0][1]);
printf("%d\n", a[0][2]);
printf("%d\n", a[1][0]);
printf("%d\n", a[1][1]);
printf("%d\n", a[1][2]);
return 0;
}
ビルド実行結果
1
2
3
4
5
6
1👈ここです
2
3
4
5
6
1👈ここです
2
3
4
5
6
**aを用いた
printf("%d\n", **a);
を実行することにより
int型の2次元配列aの先頭の配列変数
a[0][0]
に格納されている
数値データ1を表示することができましたね」
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます