🌻天国にいけるC++言語入門🌻 進化し続けるオブジェクト指向プログラミング ver3.2307
文字列nekoをコンピュータのメモリに格納する char hairetu[]="neko"; と char* hairetu[]="neko"; では何がちがうのでしょうか?
文字列nekoをコンピュータのメモリに格納する char hairetu[]="neko"; と char* hairetu[]="neko"; では何がちがうのでしょうか?
文字列データ"neko"をコンピュータのメモリに格納する
配列宣言
char hairetu[]="neko";
と
ポインタ変数宣言
char* hairetu[]="neko";
では何がちがうのでしょうか?
ソーラー「よしっ それでは説明といこうかな。」
マックス「は~~いっ ソーラーさん。」
ソーラー「まずは
char hairetu[]="neko";
の場合からだね。
配列宣言
char hairetu[]="neko";
が行われると
文字列データ"neko"は
配列宣言
char hairetu[]="neko";
により生成される
char型の配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
に
hairetu[0]='n'
hairetu[1]='e'
hairetu[2]='k'
hairetu[3]='o'
hairetu[4]='\0'
のように格納されます。
文字列データ"neko"をメモリに格納するために
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
が作成されたようにみえます。
🍓🍓 実はchar hairetu[]="neko";が実行されると🍓🍓
文字列データ"neko"を格納した
つまり
文字データ
'n'
'e'
'k'
'o'
'\0'
を格納したメモリが存在しており
例えていえば
005BFD83
005BFD84
005BFD85
005BFD86
005BFD87
というアドレス番号のメモリが存在しており
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
と名前のつけられたメモリが存在しているわけではありません。
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
は
005BFD83
005BFD84
005BFD85
005BFD86
005BFD87
というアドレス番号のメモリに
アクセスするための窓口になっているのです。
そのことは
🍋ポインタ変数宣言 char* hairetu="neko";🍋
が行われた場合でもおなじです
char* hairetu="neko";
が実行されたときも
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
が作製されますが
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
と名前の付けられたメモリに直接
文字列データ"neko"が
hairetu[0]='n'
hairetu[1]='e'
hairetu[2]='k'
hairetu[3]='o'
hairetu[4]='\0'
と格納されているわけではありません。
いったいど~いうこと???
とおもわれますね。
配列を使って
char hairetu[]="neko";
と
文字列"neko"データを格納したとき
も
ポインタ変数を使って
char* hairetu[]="neko";
と
文字列"neko"データを格納したときも
おなじようなことがおこなわれています。
ポインタ変数を使って
文字列データを格納する命令文
char* hairetu="neko";
が実行されると
まず コンピューターのあるどこかのメモリ
例えるなら
0019FF54
0019FF55
0019FF56
0019FF57
0019FF58
というアドレス番号のメモリに
0019FF54というアドレス番号の付いたメモリに'n'
0019FF55というアドレス番号の付いたメモリに'e'
0019FF56というアドレス番号の付いたメモリに'k'
0019FF57というアドレス番号の付いたメモリに'o'
0019FF58というアドレス番号の付いたメモリに'\0'
のように
文字列データ"neko"が格納されます
どのメモリに格納されるかはメモリの使用状況によります。
そして
その次は
char* hairetu="neko";
により
文字列データ"neko"が格納された連続したメモリの先頭のメモリのアドレス
つまり
文字データ'n'を格納したメモリのアドレス
0019FF54
が
ポインタ変数hairetuに格納されることになります。
文字列データ"neko"が格納されたメモリのアドレス
つまり
文字データ'n'を格納したメモリのアドレス
0019FF54
が
ポインタ変数hairetu
に格納されるとどういうことがおこるのでしょうか?
そのとき
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
のアドレスを格納しているポインタ変数
hairetu
hairetu+1
hairetu+2
hairetu+3
hairetu+4
には
0019FF54というアドレス番号
0019FF55というアドレス番号
0019FF56というアドレス番号
0019FF57というアドレス番号
0019FF58というアドレス番号
があたえられることになります。
そのとき
*hairetu
*(hairetu+1)
*(hairetu+2)
*(hairetu+3)
*(hairetu+4)
は
0019FF54というアドレス番号
0019FF55というアドレス番号
0019FF56というアドレス番号
0019FF57というアドレス番号
0019FF58というアドレス番号
に格納されている文字データを表すことになるのですが
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
は
*hairetu
*(hairetu+1)
*(hairetu+2)
*(hairetu+3)
*(hairetu+4)
をあらわしており
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
は
0019FF54というアドレス番号
0019FF55というアドレス番号
0019FF56というアドレス番号
0019FF57というアドレス番号
0019FF58というアドレス番号
のついたメモリ
に格納されている文字データをあらわすことになります。
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
は
0019FF54というアドレス番号
0019FF55というアドレス番号
0019FF56というアドレス番号
0019FF57というアドレス番号
0019FF58というアドレス番号
のメモリ
に格納されている文字データをあらわすので
cout << hairetu[0] << "\n";
cout << hairetu[1] << "\n";
cout << hairetu[2] << "\n";
cout << hairetu[3] << "\n";
cout << hairetu[4] << "\n";
が実行されると
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
に文字データ
'n'
'e'
'k'
'o'
'\0'
が格納されているので
ビルド実行結果は
n
e
k
o
(空白)
と表示されます
つまり
ポインタ変数宣言
char* hairetu="neko";
が実行された場合
生成された配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
に文字列データ"neko"が格納されているのではありません。
そうではなく
0019FF54というアドレス番号
0019FF55というアドレス番号
0019FF56というアドレス番号
0019FF57というアドレス番号
0019FF58というアドレス番号
のメモリに
文字列データ"neko"が格納されていて
それらのメモリのアドレスが
ポインタ変数hairetuに
つまり
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
のアドレスを格納しているポインタ変数
hairetu
hairetu+1
hairetu+2
hairetu+3
hairetu+4
に
格納された結果
*hairetu
*(hairetu+1)
*(hairetu+2)
*(hairetu+3)
*(hairetu+4)
は
0019FF54というアドレス番号
0019FF55というアドレス番号
0019FF56というアドレス番号
0019FF57というアドレス番号
0019FF58というアドレス番号
のメモリに
格納されている文字データをあらわすことになり
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
は
*hairetu
*(hairetu+1)
*(hairetu+2)
*(hairetu+3)
*(hairetu+4)
をあらわすので
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
は
0019FF54というアドレス番号
0019FF55というアドレス番号
0019FF56というアドレス番号
0019FF57というアドレス番号
0019FF58というアドレス番号
のメモリに
格納されている文字データをあらわすことになったというわけです。
ですので
このとき
コンピュータのメモリ装置には
0019FF54というアドレス番号
0019FF55というアドレス番号
0019FF56というアドレス番号
0019FF57というアドレス番号
0019FF58というアドレス番号
のメモリに
文字データ
'n'
'e'
'k'
'o'
'\0'
を格納した
メモリだけが存在しています。
文字データ
'n'
'e'
'k'
'o'
'\0'
を格納した
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
と名付けられたメモリは存在していません。
ですが
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
を用いて
0019FF54というアドレス番号
0019FF55というアドレス番号
0019FF56というアドレス番号
0019FF57というアドレス番号
0019FF58というアドレス番号
のメモリに
アクセスすることができるというわけです。
次に
今のように
char*型のポインタ変数宣言を行い作製されたポインタ変数を使って
char *hairetu="neko";
と文字列データ"neko"をメモリに格納した後
さらに
同じ名前の
ポインタ変数hairetuを使って
hairetu="nyao";
と文字列データ"nyao"を格納した場合について
考察してみます。
さきほど
char* hairetu="neko";
により
0019FF54というアドレス番号
0019FF55というアドレス番号
0019FF56というアドレス番号
0019FF57というアドレス番号
0019FF58というアドレス番号
のメモリに
文字データ
'n'
'e'
'k'
'o'
'\0'
が格納されました。
次に
hairetu="nyao";
が実行されると
0019FF54というアドレス番号
0019FF55というアドレス番号
0019FF56というアドレス番号
0019FF57というアドレス番号
0019FF58というアドレス番号
のメモリとは違う
アドレス番号
00D3FA41
00D3FA42
00D3FA43
00D3FA44
00D3FA45
のメモリに
文字列データ"nyao"は
アドレス番号00D3FA41のメモリに'n'
アドレス番号00D3FA42のメモリに'y'
アドレス番号00D3FA43のメモリに'a'
アドレス番号00D3FA44のメモリに'0'
アドレス番号00D3FA45のメモリに'\0'
と格納されます。
アドレス番号
00D3FA41
00D3FA42
00D3FA43
00D3FA44
00D3FA45
は説明のための仮のアドレス番号です。
このとき
hairetu="nyao";
により生成された配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
に
文字列データ"nyao"が
hairetu[0]='n'
hairetu[1]='y'
hairetu[2]='a'
hairetu[3]='o'
hairetu[4]='\0'
と格納されているのではありません。
繰り返して述べますと
hairetu="nyao";
により
まず
アドレス番号
00D3FA41
00D3FA42
00D3FA43
00D3FA44
00D3FA45
のメモリに
文字列データ"nyao"が
アドレス番号00D3FA41のメモリに'n'
アドレス番号00D3FA42のメモリに'y'
アドレス番号00D3FA43のメモリに'a'
アドレス番号00D3FA44のメモリに'0'
アドレス番号00D3FA45のメモリに'\0'
と格納されます。
そして
char* hairetu="nyao";
の実行により
先頭のアドレス番号00D3FA41のアドレスが
ポインタ変数hairetuに格納されることにより
アドレス番号
00D3FA41
00D3FA42
00D3FA43
00D3FA44
00D3FA45
が
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
のアドレスを格納しているポインタ変数
hairetu
hairetu+1
hairetu+2
hairetu+3
hairetu+4
に与えられた結果
*hairetu
*(hairetu+1)
*(hairetu+2)
*(hairetu+3)
*(hairetu+4)
は
アドレス番号00D3FA41
アドレス番号00D3FA42
アドレス番号00D3FA43
アドレス番号00D3FA44
アドレス番号00D3FA45
のメモリに
格納されている文字データ
'n'
'y'
'a'
'o'
'\0'
をあらわすことになります。
*hairetu
*(hairetu+1)
*(hairetu+2)
*(hairetu+3)
*(hairetu+4)
は
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
をあらわしているので
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
は
アドレス番号00D3FA41
アドレス番号00D3FA42
アドレス番号00D3FA43
アドレス番号00D3FA44
アドレス番号00D3FA45
のメモリに
格納されている文字データ
'n'
'y'
'a'
'o'
'\0'
をあらわすことになります。
そして
char* hairetu="neko";
の実行のあと
hairetu="nyao";
が実行された
この状態の場合
0019FF54というアドレス番号
0019FF55というアドレス番号
0019FF56というアドレス番号
0019FF57というアドレス番号
0019FF58というアドレス番号
のメモリに
文字データ
'n'
'e'
'k'
'o'
'\0'
は保存されたまま
別の
アドレス番号
00D3FA41
00D3FA42
00D3FA43
00D3FA44
00D3FA45
のメモリに
文字列データ"nyao"が
アドレス番号00D3FA41のメモリに'n'
アドレス番号00D3FA42のメモリに'y'
アドレス番号00D3FA43のメモリに'a'
アドレス番号00D3FA44のメモリに'0'
アドレス番号00D3FA45のメモリに'\0'
と
文字列データ"nyao"が格納されることになります。
文字列データ"neko"を格納している
アドレス番号0019FF54
アドレス番号0019FF55
アドレス番号0019FF56
アドレス番号0019FF57
アドレス番号0019FF58
のメモリに
文字列データ"nyao"が上書きされるということはありません。
そして
cout << hairetu[0] << "\n";
cout << hairetu[1] << "\n";
cout << hairetu[2] << "\n";
cout << hairetu[3] << "\n";
cout << hairetu[4] << "\n";
が実行されると
ビルド実行結果は
n
y
a
o
(空白)
が
コマンドプロンプト画面に表示されます。
このとき
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
は
アドレス番号00D3FA41
アドレス番号00D3FA42
アドレス番号00D3FA43
アドレス番号00D3FA44
アドレス番号00D3FA45
のメモリに
アクセスして
格納されている文字データ
'n'
'y'
'a'
'o'
'\0'
をあらわしており
アドレス番号0019FF54
アドレス番号0019FF55
アドレス番号0019FF56
アドレス番号0019FF57
アドレス番号0019FF58
のメモリに格納されている
文字データ
'n'
'e'
'k'
'o'
'\0'
をあらわすことにはならないので
cout << hairetu[0] << "\n";
cout << hairetu[1] << "\n";
cout << hairetu[2] << "\n";
cout << hairetu[3] << "\n";
cout << hairetu[4] << "\n";
を実行しても
アドレス番号0019FF54
アドレス番号0019FF55
アドレス番号0019FF56
アドレス番号0019FF57
アドレス番号0019FF58
のメモリに格納されている
文字データ
'n'
'e'
'k'
'o'
'\0'
を
cout出力表示することはできません。
そこで どうしても
文字列データ"neko"を
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
を用いた命令文
cout << hairetu[0] << "\n";
cout << hairetu[1] << "\n";
cout << hairetu[2] << "\n";
cout << hairetu[3] << "\n";
cout << hairetu[4] << "\n";
を使ってcout出力表示したい場合は
char* hairetu="neko";
hairetu="nyao";
が実行された後
さらに
hairetu="neko";
を実行すればよいことになります。
そのときは
さきほどの
アドレス番号0019FF54
アドレス番号0019FF55
アドレス番号0019FF56
アドレス番号0019FF57
アドレス番号0019FF58
のメモリに格納されている
文字列データ"neko"の
文字データ
'n'
'e'
'k'
'o'
'\0'
とは別に
さらに新たに
アドレス番号
00EFF32C
00EFF32D
00EFF32E
00EFF32F
00EFF330
のメモリに
アドレス番号00EFF32Cのメモリに'n'
アドレス番号00EFF32Dのメモリに'e'
アドレス番号00EFF32Eのメモリに'k'
アドレス番号00EFF32Fのメモリに'o'
アドレス番号00EFF330のメモリに'\0'
と文字列データ"neko"が格納されます。
そして
hairetu="neko";
が実行されると
生成された
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
のアドレスを格納しているポインタ変数
hairetu
hairetu+1
hairetu+2
hairetu+3
hairetu+4
には
アドレス番号
00EFF32C
00EFF32D
00EFF32E
00EFF32F
00EFF330
があたえられることになります。
*hairetu
*(hairetu+1)
*(hairetu+2)
*(hairetu+3)
*(hairetu+4)
は
アドレス番号00EFF32Cのメモリに格納されている文字データ'n'
アドレス番号00EFF32Dのメモリに格納されている文字データ'e'
アドレス番号00EFF32Eのメモリに格納されている文字データ'k'
アドレス番号00EFF32Fのメモリに格納されている文字データ'o'
アドレス番号00EFF330のメモリに格納されている文字データ'\0'
をあらわすことになります。
そうなると
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
は
*hairetu
*(hairetu+1)
*(hairetu+2)
*(hairetu+3)
*(hairetu+4)
をあらわしているので
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
の格納している文字データは
アドレス番号00EFF32Cのメモリに格納されている文字データ'n'
アドレス番号00EFF32Dのメモリに格納されている文字データ'e'
アドレス番号00EFF32Eのメモリに格納されている文字データ'k'
アドレス番号00EFF32Fのメモリに格納されている文字データ'o'
アドレス番号00EFF330のメモリに格納されている文字データ'\0'
となります。
ですので
このとき
cout << hairetu[0] << "\n";
cout << hairetu[1] << "\n";
cout << hairetu[2] << "\n";
cout << hairetu[3] << "\n";
cout << hairetu[4] << "\n";
が実行されると
ビルド実行結果
n
e
k
o
(空白)
が表示されることになります。」
ソーラー「
おや? こんなところに🌸花びら🌸が・・・
・・・なんだろうか・・・
花びらをすくい上げるソーラー。
すると・・・
ソーラーさん 今度、私たちのところに遊びにいらしてください
・・・
ソーラー「おもわぬ招待をうけたようだね。
では今度遊びに伺おうとしようかな😊」
マックス「お、なんか いいことあったみたいだな」
ソーラー「また 楽しみがふえたね。
それでは配列を使った
char hairetu[]="neko";
をつかって
文字列データ"neko"を格納したとき
と
ポインタ変数を使った
char* hairetu="neko";
をつかって
文字列データ"neko"をメモリに格納したとき
ではなにがちがうのかというと
それは
char hairetu[]="neko";
をつかって
文字列データ"neko"をメモリに格納したときでは
次に
hairetuとは別の配列hairetuboxを使った
char hairetubox[]="nyao";
をつかって
文字列データ"nyao"をメモリに格納したとき
'n'・・・アドレス005BFD83
'e'・・・アドレス005BFD84
'k'・・・アドレス005BFD85
'o'・・・アドレス005BFD86
'\0'・・・アドレス005BFD87
'n'・・・アドレス005BFD88
'y'・・・アドレス005BFD89
'a'・・・アドレス005BFD8A
'o'・・・アドレス005BFD8B
'\0'・・・アドレス005BFD8C
と順序良く並んで文字データが格納されていくのですが
ポインタ変数を使った
char* hairetu="neko";
をつかって
文字列データ"neko"をメモリに格納したときでは
次に
hairetu="nyao";
をつかって
文字列データ"nyao"をメモリに格納すると
'n'・・・アドレス0019FF44
'e'・・・アドレス0019FF45
'k'・・・アドレス0019FF46
'o'・・・アドレス0019FF47
'\0'・・・アドレス0019FF48
'n'・・・アドレス0019FF53
'y'・・・アドレス0019FF54
'a'・・・アドレス0019FF55
'o'・・・アドレス0019FF56
'\0'・・・アドレス0019FF57
のようにランダムにメモリに文字データが格納されます。
☆ ☆ ☆ ☆ ☆ ☆ ☆
'\0'・・・アドレス0019FF48
と
'n'・・・アドレス0019FF53
は
アドレス番号が
5ほどはなれています。
(アドレス番号がきれいに並ぶ場合もあります)
☆ ☆ ☆ ☆ ☆ ☆ ☆
このようにポインタ変数をつかって
char* hairetu="neko";
hairetu="nyao";
を実行して
文字列データ"neko"を
格納したあと
新たに文字列データ"nyao"を格納していく場合は
配列を使って
char hairetu[]="neko";
char hairetubox[]="nyao";
を実行したときとは違い
必ずしも連続して
文字データがメモリに格納されることはありません」
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます