配列のポインタ変数とは一体何のことでしょうか?
ここで ソーラーさんは皆を笑わせようとおもいっきり😋間違ってきます。
ご注意ください。
アレサ 「ではでは(^^)
変数aのアドレス&aをポインタ変数ptaに格納できたところで
配列とポインタ変数はどのような関係になっているのでしょう?
考察してみましょう(^^)ね、ソーラーさん」
ソーラー「ええっ😝😝😝
配列とポインタ変数の関係?????
?????
?????
はい?なんのこと?
まるで
きゅうりとポテトチップスの関係を聞かれてるみたいだ・・
なんの関係もな~し
配列とポインタ変数の関係はなしです!
これで終了
配列とポインタ変数の関係は簡単です!
いいね。 アレサ」
アレサ 「はう?」
ソーラー 「い、いや、ちょっといってみただけなんだよっ
はうあうあうあ
い、いや~~~
と、とにかく
配列は確か・・・
例えば int hairetu [3]={1,2,3};
と配列宣言、初期化したら
この配列hairetu内に自動的に
3つの配列変数
hairetu [0]
hairetu [1]
hairetu [2]
ができ
数値1,2,3が、それぞれ
配列変数
hairetu[0]には1
hairetu[1]には2
hairetu[2]には3
が格納されるシステムだった。
______________________________________________
配列宣言、初期化を
int hairetu[3]={1,2,3};
ではなく
もっと丁寧に
int hairetu[3]; (要素数3)
hairetu[0]=1;
hairetu[1]=2;
hairetu[2]=3;
と記述する方法もあるね。
______________________________________________
配列を使えば
int a=1;
int b=2;
int c=3;
👆
このようにa,b,cのint型変数宣言&初期化をおこなわなくても
int hairetu[3]={1,2,3};
で済むから便利なんだよね~~~
配列
その仕組みは簡単、簡単(^^)/
ふぅ ふふふふふふ
そして
ポインタ変数とはアドレスを格納する変数のことだった。
(前のエピソードでも見てきたようにポインタ変数に
ポインタ変数を代入して
ポインタ変数に格納されているアドレスを
ポインタ変数に渡すこともできるよ)
これも簡単だね。(^^)/
ふはは
ところで
まえから思っていたんだけど
先程の配列変数に数値を代入する
hairetu[0]=1;
hairetu[1]=2;
hairetu[2]=3;
において
変数aを変数宣言後に
a=1;
と数値1が代入できたように
hairetu[0]に数値1が代入できるのなら
《《配列変数hairetu[0]って普通に変数なんじゃない?,
もしくは変数としての性質をもつ?》》
そう思わないかい? アレサ
そこで
配列変数hairetu[0]をふつうの変数とみなす。
すると
配列変数hairetu[0]に数値1が格納されているということは
配列変数hairetu[0]という名前の付いたメモリに数値1が格納されている
(または配列変数hairetu[0]がアクセスしているメモリに数値1が格納されている)
ということであり
もちろん
そのメモリにはアドレスがあることになる。
つまり
変数aに変数aのアドレス&aがあるように
配列変数hairetu[0]にも
配列変数hairetu[0]のアドレス&hairetu[0]があることになる。
そこで変数であろう配列変数hairetu[0]のアドレスである
&hairetu[0]がどのような値を持っているのかを
プログラムを組んで求めてみる。」
#include <stdio.h>
int main(void){
int hairetu[3]={1,2,3};
printf("%p\n",& hairetu[0]);
return 0;
}
コンパイル結果
0019FF4C
ソーラー「
数値データ1を格納しているhairetu[0]のアドレスは0019FF4C(*^^)v
あう、無事に求めることができた・・
おおウウウぉぉぉ いいんじゃな~い
ねえ、アレサ
コンパイラが
hairetu[0]と&を組み合わせた
&hairetu[0]のアドレスを読み取れたとなると
やはり
配列変数hairetu[0]は
変数hairetu[0]としての性質をもっているみたいだね。
となると
pthairetu[0]をポインタ変数宣言することにより
作製されたポインタ変数pthairetu[0]に
配列変数hairetu[0]のアドレス&hairetu[0]を
格納することができるはずだよね。
ポインタ変数とは
変数のアドレスを格納するための変数だから
変数ともいえるhairetu[0]のアドレス&hairetu[0]を
格納することのできるポインタ変数
pthairetu[0]
を作ることができるのは普通のことだもんね💖」
さあ どうかな?
solarplexussより
ソーラー「
わおおぅ いい流れじゃん・・・
さっそく
ポインタ変数pthairetu[0]をつくってhairetu[0]のアドレス、
&hairetu[0]を
ポインタ変数pthairetu[0]に格納してみよぅ
その手順は次のようになるね!
まず
配列宣言int hairetu[3]={1,2,3};
によって
hairetu[0]に1を格納した後
配列変数hairetu[0]のアドレスを格納するためのポインタ変数
pthairetu[0]を
int* pthairetu[0];と
ポインタ変数宣言する
その後
作製された
ポインタ変数pthairetu[0]を初期化するために
配列変数hairetu[0]のアドレス&hairetu[0]を
pthairetu[0]=&hairetu[0];と
ポインタ変数pthairetu[0]に代入する。
後は
ポインタ変数pthairetu[0]に格納されているアドレスを
%p出力変換指定子をつかって16進数でprintf出力表示してみる。
それでは
その手順に沿ったプログラムを構成してみます
#include <stdio.h>
int main(void){
int hairetu[]={1,2,3};
printf("%p\n",& hairetu[0]);/*ここで、まず hairetu[0]のアドレスを確かめています*/
int* pthairetu[0]; /*〇pthairetu[0]のポインタ変数宣言を行う*/
pthairetu[0]=&hairetu[0];/*ポインタ変数pthairetu[0]にhairetu[0]のアドレス&hairetu[0]を代入して初期化する*/
printf("%p\n", pthairetu[0]);/*ここで、ポインタ変数pthairetu[0]に
どのようなアドレスが格納されているか確認する*/
return 0;
}
ソーラー「まあ printf("%p\n", pthairetu[0]);
を行うと
ふつうに ポインタ変数pthairetu[0]に格納されている
hairetu[0]のアドレス&hairetu[0]が表示されるはずだよね。」
うちもそう思います
solarplexussより
アレサ「ソーラーさん 、こういうの本当に お好きですね」
ソーラー「ははっ😊 マックスにもよくいわれるよ
それでは😊😊😊
🍅コンパイルっ🍅
コンパイル結果
EAZY IDECの場合
0019FF4C
0019FF4C
Visual Studioの場合
ビルド実行結果
エラー (アクティブ) E0094 配列のサイズは 0 より大きくなければなりません
エラー C2466 サイズが 0 の配列を割り当てまたは宣言しようとしました。
エラー C2133 'pthairetu': サイズが不明です。 9
ソーラー「Visual Studioのビルド結果はともかく
EAZY IDECのコンパイル結果をみてよ
(みなさんC++言語でお会いしましょう)
おおおおおぅぅぅ
やった・・・ふつうにやったよ
アレサ・・
おお娘やぁぁああああっ・・・
無事に
配列変数hairetu[0]のアドレスがポインタ変数pthairetu[0]
に格納できているよ~。
おっお父さんは嬉しいよぉ~お~~~~
実はね アレサ
配列変数
hairetu[0]は
変数同様にあつかえるかどうか
わからない
だから&hairetu[0]はちゃんとポインタ変数pthairetu[0]に格納できるか
どうかな?
とおもっていたんだよ
⦅ 配列内のいれものの一つである配列変数hairetu[0]といっても ⦆
ようは、変数なんだから
そのアドレスは
ポインタ変数pthairetu[0]に格納できるというだけの話なんだね。
ふふふ~ん っていうかおわったかな?
これで説明?」
アレサ「ピンポ~ン、大正解です、ソーラーさん」
ソーラー「・・・ふふふ
最初は配列とポインタ変数の関係???
なんのことか
さっぱりだったんだけど…
なんかいがいと簡単におわったね😊」
アレサ 「 ソーラーさん すごく展開がはやいです
ずんずんすすんでいくから」
ソーラー「しまったあ、娘さんやぁ
わしゃあ・・・ボケるの忘れるとは・・・」
アレサ「正確には
ピンポ~ン、大正解です、
💖ここまでは💖
でよいのですよね?
ソーラーさん」
ソーラー「!!!!!!!!!」
アレサ 「もう、こんなにながい文章にわたって
うまいぐあいにボケをもってきましたのは
今までで はじめてではないですの?」
ソーラー「ぎくぅ・・・な、なんのこと」
アレサ「読者のみなさん
今のトリックにお気付きになられましたか
ネタ明かしをいたします
今のプログラムには
ポインタ変数pthairetu[0]に間接参照演算子*を用いた
*pthairetu[0]を使用して
配列変数
hairetu[0]の中身に格納されている数値データ、
この場合は
その数値データは1です。
その数値データ1をprintf出力表示する命令文
printf("%d\n", *pthairetu[0]);
はかかれていませんね。
とても基本的な命令文です」
ソーラー「ぎくぅ・・・」
アレサ
「
その命令文
printf("%d\n", *pthairetu[0]);を
実行すると1が出力されなければなりませんね😋」
ソーラー「😋😋もっと、もっとぉ😋😋もっと、もっとぉ」
アレサ「😋😋もっと、もっとですか・・・ひくっひくっひく・・
そこでこの命令文
printf("%d\n", *pthairetu[0]);
を先のプログラムに追加し
コンパイル結果をたしかめてみると
#include <stdio.h>
int main(void){
int hairetu[]={1,2,3};
printf("%p\n",&hairetu[0]);/*ここで、まず hairetu[0]のアドレスを確かめる*/
int* pthairetu[0]; /*pthairetu[0]のポインタ変数宣言を行う*/
pthairetu[0]=&hairetu[0];/*ポインタ変数pthairetu[0]にhairetu[0]のアドレス&hairetu[0]を代入して初期化する*/
printf("%p\n", pthairetu[0]);/*ここで、pthairetu[0]にどのような数値、つまり、アドレスが格納されているか確認する*/
printf("%d\n", *pthairetu[0]);
/*😊追加された命令文はここです
いったい*pthairetu[0]にどのような数値が格納されているのでしょうか😊*/
return 0;
}
(EAZY IDECの場合)
コンパイル結果
0019FF4C (👈これはhairetu[0]のアドレスを表しています)
0019FF4C (👈これはpthairetu[0]に格納されているアドレスを表しています)
1703756 ( 👈これはアドレス&hairetu[0]のメモリに格納されている数値を表しています
(Visual Studioの場合)
エラー (アクティブ) E0094 配列のサイズは 0 より大きくなければなりません
エラー C2466 サイズが 0 の配列を割り当てまたは宣言しようとしました。
エラー C2133 'pthairetu': サイズが不明です。
(なぜVisual Studioでこのような表示が出てくるのかは
すぐに理解できるようになります
solarplexussより」
アレサ「
この(EAZY IDECの場合)の
コンパイル結果の3行目がおかしいときづかれるはずです
ポインタ変数pthairetu[0]にhairetu[0]のアドレス&hairetu[0]を代入して
初期化したので
pthairetu[0]に
*をもちいた
*pthairetu[0]には1が格納されているはずです
printf("%d\n", *pthairetu[0]);
を実行すると
アドレスhairetu[0]のメモリに
格納されている数値1が出力されるはずですが・・・
1703756が表示されています
さらに
(Visual Studioの場合)ではビルド実行すらできません
このことは
🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋
🍋ポインタ変数 🍋
🍋pthairetu[0]がhairetu[0]のポインタ変数として機能していない 🍋
🍋 🍋
🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋
ことをあらわしています。
原因は
もともと配列変数hairetu[0]が変数として完全には機能していないため
とおもわれますの ね、ソーラーさん」
太陽の光に 照らされに照らされ喜びだすソーラー
😋😋😋😋😋😋
ソーラー 「ぐごげぇぇぇぇぇぇぇぇぇ😋😋😋😋😋😋
🌳pthairetu[0]はポインタ変数として機能している🌳
がああああ😋😋😋😋😋😋
🌳pthairetu[0]はポインタ変数として機能している🌳
がああああ😋😋😋😋😋😋
シンプルに全否定されてしまったあぁぁぁぁぁぁぁ
おおおおおおおおおおおおおおおおおおおお
おおおおおおおおおお
もっと、もっと~~~😋😋😋」
アレサ 「つまりこのエピソードの冒頭で
配列とポインタ変数の関係はなし
と
ソーラーさんの語った真の意味とは・・・」
ソーラー「はあ😋はあ😋はあ😋」
アレサ 「つまり
配列とポインタ変数の関係はなし
と
ソーラーさんの語った真の意味とは・・・」
ソーラー「おぅぅぅおおおおおお、はあ、はあ」
地面に手をつきもがきだすソーラー。
アレサ 「配列変数hairetu[0]のアドレスを
ポインタ変数pthairetu[0]をつくり、
格納することはできても
*pthairetu[0]はhairetu[0]に格納されている
数値を表していない
すなわち
ソーラー「はあ、はあ、はああああああ,oo,oooooxtu」
アレサ「
😚配列変数hairetu[0]
にはうまく適応した
ポインタ変数を新たにつくることができない。😝
ということなのです。」
ソーラー「つくることができない。
そう
これで解決
配列とポインタ変数の関係は簡単でしたね。(^_-)-☆」
配列のポインタ変数については
まだまだお話はつづきます
solarplexussより
このプログラムで
配列変数
hairetu[0]のアドレスをポインタ変数pthairetu[0]
に格納してお話をすすめていました。
今度はhairetu[0]をhairetu[1]に変えて
配列変数
hairetu[1]のアドレスを
ポインタ変数pthairetu[1]を作成し
pthairetu[1]に格納してみます
すると・・・
#include <stdio.h>
int main(void){
int hairetu[3]={1,2,3};
printf("%p\n",&hairetu[1]);
int* pthairetu[1];
pthairetu[1]=&hairetu[1];
printf("%p\n", pthairetu[1]);
printf("%d\n", *pthairetu[1]);
/*😊追加された命令文はここです
いったい*pthairetu[1]にどのような数値が格納されているのでしょうか😊*/
return 0;
}
(EAZY IDECの場合)
コンパイル結果
0019FF50
0019FF50
2
(Visual Studioの場合)
ビルド実行結果
00BEF830
00BEF830
2
さらにVisual Studioの場合
おまけで
コマンドプロンプト画面とは
別の画面が表示されます。
画面には
program:
C:\Users\solarplexuss\source\repos\Project8\Debug\Project8.exe
module:
C:\Users\solarplexuss\source\repos\Project8\Debug\Project8.exe
File:
Debug Error!
Run-Time Check Failure#2-Stack around the variable 'pthairetu' was corrupted.
(Press Retry to debug the application)
と文章が表示され
さらに
中止 再試行 無視
の3つのボタンが表示されます
このエラー文はひとまずおいておきましょう。
なぜか
hairetu[0]をhairetu[1]に変えただけの
同じプログラムなのに
きちんと,
*pthairetu[1]が機能し
printf("%d\n", *pthairetu[1]);
によって
hairetu[1]に格納されている数値2
が表示されています。
今度はhairetu[1]をhairetu[2]に変えて
プログラムをコンパイルしてみます。
#include <stdio.h>
int main(void){
int hairetu[3]={1,2,3};
printf("%p\n",&hairetu[2]);
int* pthairetu[2];
pthairetu[2]=&hairetu[2];
printf("%p\n", pthairetu[2]);
printf("%d\n", *pthairetu[2]);
/*😊追加された命令文はここです
いったい*pthairetu[2]にどのような数値が格納されているのでしょうか😊*/
return 0;
}
(EAZY IDECの場合)
コンパイル結果
0019FF54
0019FF54
3
(Visual Studioの場合)
ビルド実行結果
0075FEEC
0075FEEC
3
ここでも
Visual Studioの場合
さらにおまけで
コマンドプロンプト画面とは
別の画面が表示されます。
画面には
program:
C:\Users\solarplexuss\source\repos\Project8\Debug\Project8.exe
module:
C:\Users\solarplexuss\source\repos\Project8\Debug\Project8.exe
File:
Debug Error!
Run-Time Check Failure#2-Stack around the variable 'pthairetu' was corrupted.
(Press Retry to debug the application)
と文章が表示され
さらに
中止 再試行 無視
の3つのボタンが表示されます
このエラー文はひとまずおいておきましょう。
直ぐに後のエピソードで理解できるようになるでしょう。
このプログラムの実行結果でも
きちんと,
*pthairetu[2]が機能し
printf("%d\n", *pthairetu[2]);
によって
hairetu[2]に格納されている数値3
が表示されています。
よって
hairetu[0]のアドレスを格納した
pthairetu[0]のみが
うまくポインタ変数として機能していないのがわかります。」
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます