文字列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";


を実行したときとは違い


必ずしも連続して


文字データがメモリに格納されることはありません」


  • Twitterで共有
  • Facebookで共有
  • はてなブックマークでブックマーク

作者を応援しよう!

ハートをクリックで、簡単に応援の気持ちを伝えられます。(ログインが必要です)

応援したユーザー

応援すると応援コメントも書けます

新規登録で充実の読書を

マイページ
読書の状況から作品を自動で分類して簡単に管理できる
小説の未読話数がひと目でわかり前回の続きから読める
フォローしたユーザーの活動を追える
通知
小説の更新や作者の新作の情報を受け取れる
閲覧履歴
以前読んだ小説が一覧で見つけやすい
新規ユーザー登録無料

アカウントをお持ちの方はログイン

カクヨムで可能な読書体験をくわしく知る