🌞🌞🌞ポインタ変数を使って文字列データをメモリに格納していく場合 1番最後にデータを格納したメモリのアドレスがポインタ変数に格納されます🌞🌞🌞

(Visual Studio2018の場合)配列と違いポインタ変数はポインタ変数名を変更しなくても文字列データを💖どんどん💖メモリに格納することができます

Visual Studio2019以降のヴァージョンではポインタ変数を使って

文字列データをメモリに格納する機能は削除されています


ご注意くださいね💖





ソーラー「それでは


char hairetu[ ]="neko";

char* hairetu="neko";の



違いを考察してみるよ。


まずは

char hairetu[ ]="neko";

のように


配列を使って

文字列データ"neko"をメモリに格納してみます。


#include <stdio.h>


int main(void){


char hairetu[]="neko";


printf("%s\n",hairetu);


return 0;

}


コンパイル結果


EAZY IDECの場合

neko


Visual Studioの場合

neko


アレサ「ソーラーさん


普通に配列を使って


メモリに


文字列データ"neko"が格納され


printf("%s\n",hairetu);


により


コマンドプロンプト画面に


neko


が表示されていますね。


このとき


配列hairetuの


配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]


には

'n'

'e'

'k'

'o'

'\0'

hairetu[0]='n'

hairetu[1]='e'

hairetu[2]='k'

hairetu[3]='o'

hairetu[4]='\0'


と格納されています。」


ソーラー「そうだね。


配列名はhairetuのまま


今度は


char hairetu[ ]="neko";

char hairetu[ ]="nyao";

//👆🌞このような同じ配列名を用いた配列宣言を再度行う記述はよくありません

ここでは配列の仕組みを考察するためにおこなっています//



のように


文字列データ"neko"

のあとに

文字列データ"nyao"


をメモリに格納するプログラムを実行してみるね。


#include <stdio.h>


int main(void){


char hairetu[ ]="neko";

char hairetu[ ]="nyao";


printf("%s\n",hairetu);


return 0;

}


コンパイル結果


EAZY IDEC の場合

nyao



Visual Studioの場合


エラー C2374 'hairetu': 再定義されています。2 回以上初期化されています。


アレサ「まずは

EAZY IDEC の場合ですが


このとき


配列hairetuの


配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]


には

'n'

'y'

'a'

'o'

'\0'

hairetu[0]='n'

hairetu[1]='y'

hairetu[2]='a'

hairetu[3]='o'

hairetu[4]='\0'


と格納されています。


最初に


配列hairetuの


配列変数

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'


と格納されていた

文字データ

'n'

'e'

'k'

'o'

'\0'



配列変数

hairetu[5]

hairetu[6]

hairetu[7]

hairetu[8]

hairetu[9]

にずれる形で


hairetu[5]='n'

hairetu[6]='e'

hairetu[7]='k'

hairetu[8]='o'

hairetu[9]='\0'


と格納されています


つまり


メモリ内には


'n'

'e'

'k'

'o'

'\0'


'n'

'y'

'a'

'o'

'\0'


が格納されていますが


配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]


に格納されている文字データは


'n'

'e'

'k'

'o'

'\0'

から

'n'

'y'

'a'

'o'

'\0'

になっているのですね」



ソーラー「次は


ポインタ変数hairetuを使って文字列データ"neko"をメモリに格納してみるね。


#include <stdio.h>


int main(void){


char* hairetu="neko";


printf("%s\n",hairetu);


return 0;

}


コンパイル結果


EAZY IDECの場合

neko


Visual Studioの場合

neko



アレサ「char* hairetu="neko";


hairetuのポインタ変数宣言,初期化を行って



文字列データ"neko"をメモリに格納しているのですが


このときも


配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

が生成されて


配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

には


文字データ

'n'

'e'

'k'

'o'

'\0'


hairetu[0]='n'

hairetu[1]='e'

hairetu[2]='k'

hairetu[3]='o'

hairetu[4]='\0'


と格納されています。(いるようにみえます)」


ソーラー「そうだね。


ここまでは配列をつかって


char hairetu[]="neko";


のように


文字列データ"neko"を


メモリに格納したときと同じだね。


今度は


ポインタ変数名はhairetuのまま


char* hairetu="neko";

char* hairetu="nyao";

のように

//👆🌞このような同じポインタ変数名を用いたポインタ変数宣言を再度行う記述はよくありません

ここではポインタ変数の仕組みをよりよく考察するためにおこなっています//


char* hairetu="neko";

のあとに

char* hairetu="nyao";

と記述して


文字列データ"neko"

につづいて

文字列データ"nyao"


メモリに格納するプログラムを実行してみるね。


#include <stdio.h>


int main(void){


char* hairetu="neko";

char* hairetu="nyao";


printf("%s\n",hairetu);


return 0;

}


コンパイル結果

EAZY IDECの場合

nyao


Visual Studioの場合


エラー C2374 'hairetu': 再定義されています。2 回以上初期化されています。


ソーラー「Visual Studioをお使いの方は


次のようにプログラムを記述してくださいね。」


#include <stdio.h>


int main(void){


char* hairetu="neko";

hairetu="nyao";


printf("%s\n",hairetu);


return 0;

}


Visual Studioの場合


ビルド実行結果

nyao


ソーラー「このように


プログラムを記述しておけば


char *hairetu="neko";

hairetu="nyao";


のように


hairetuのポインタ変数宣言を1回行って


作製されたポインタ変数hairetuを


🍓文字列データ"neko"を格納しているメモリのアドレス🍓


で初期化した後


(char* hairetu="neko";


は生成されるポインタ変数hairetuを


文字列データ"neko"を格納しているメモリのアドレス


で初期化しています)


次に


hairetu="nyao";

により


ポインタ変数hairetuに


🍓文字列データ"nyao"を格納しているメモリのアドレス🍓


を代入することになりますが


hairetuのポインタ変数宣言が2度行われているわけではないので


ビルドエラーがおこることはありません。」




☆  ☆  ☆  ☆  ☆  ☆  ☆


この


Visual Studioの場合のプログラムを


EAZY IDECでもコンパイル、実行できるので


EAZY IDECでも


基本的にはこのように


記述したほうがよいとおもわれます。


同じ変数名の変数宣言や同じ配列名の配列宣言


同じポインタ変数名のポインタ変数宣言


を何回も行っていると意図しないコンパイル結果になる可能性が


あります。


このエピソードではわかりやすく説明するために


同じポインタ変数名のポインタ変数宣言


を何回も行っています。


                 solarplexussより


☆  ☆  ☆  ☆  ☆  ☆  ☆


アレサ「


char* hairetu="neko";


のようにポインタ変数hairetuを使って


文字列データ"neko"をメモリに格納した後に


(このとき、ポインタ変数hairetuに代入されているのは


文字列データ"neko"を格納しているメモリのアドレスです)


char* hairetu="nyao";


のようにポインタ変数hairetuを使って


文字列データ"nyao"をメモリに格納しているのですが


(このとき、ポインタ変数hairetuに代入されているのは


文字列データ"nyao"を格納しているメモリのアドレスです)


このときも

配列hairetuの時と同じように


配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

が生成され


配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

には

文字データ

'n'

'y'

'a'

'o'

'\0'


hairetu[0]='n'

hairetu[1]='y'

hairetu[2]='a'

hairetu[3]='o'

hairetu[4]='\0'


と格納されています。(いるようにみえます)


         🍑このとき🍑


最初に


hairetuのポインタ変数宣言、初期化の命令文


char* hairetu="neko";


が実行されて


メモリに格納された

文字列データ"neko"の

文字データ

'n'

'e'

'k'

'o'

'\0'



文字列データ"nyao"

文字データ

'n'

'y'

'a'

'o'

'\0'

によって上書きされて消えてしまったわけではありません。


ここで


配列を使って文字列データを格納するときと

ポインタ変数を使って文字列データを格納するときの違いが


すこしだけ出てきます


(EAZY IDECの場合)


配列hairetuを使って文字列データをメモリに格納する


char hairetu[]="neko";

char hairetu[]="nyao";


を実行した場合

配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

には

文字データ

'n'

'y'

'a'

'o'

'\0'

配列変数

hairetu[5]

hairetu[6]

hairetu[7]

hairetu[8]

hairetu[9]

には

文字データ

'n'

'e'

'k'

'o'

'\0'

格納されることになりましたが


ポインタ変数hairetuを使って文字列データ"neko"をメモリに格納する場合


配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

には

文字データ

'n'

'y'

'a'

'o'

'\0'

格納されますが

配列変数

hairetu[5]

hairetu[6]

hairetu[7]

hairetu[8]

hairetu[9]

には

文字データ

'n'

'e'

'k'

'o'

'\0'

格納されません。


次のプログラムを実行してそのことを確認してみます。


#include <stdio.h>


int main(void) {


char* hairetu = "neko";

hairetu = "nyao";

printf("%c\n", hairetu[0]);

printf("%c\n", hairetu[1]);

printf("%c\n", hairetu[2]);

printf("%c\n", hairetu[3]);

printf("%c\n", hairetu[4]);

printf("%c\n", hairetu[5]);

printf("%c\n", hairetu[6]);

printf("%c\n", hairetu[7]);

printf("%c\n", hairetu[8]);

printf("%c\n", hairetu[9]);

return 0;

}


コンパイル結果

EAZY IDECの場合

Visual Studioの場合


n

y

a

o

(空白)

(空白)

(空白)

(空白)

(空白)

(空白)



アレサ「


配列変数

hairetu[5]

hairetu[6]

hairetu[7]

hairetu[8]

hairetu[9]

には

文字列データ"neko"が格納されていませんので

空白が表示されています。


正確には

\0が格納されているので

空白が表示されています。


ですが

メモリ内には


文字列データ"neko"も

文字列データ”nyao”も


保存されたままとなっています。」


ソーラー「???????


配列変数

hairetu[5]

hairetu[6]

hairetu[7]

hairetu[8]

hairetu[9]

には

文字列データ"neko"が格納されていないのなら


文字列データ"neko"は


メモリから消えてしまっているのじゃないかな?


たとえば


hairetu[0]='n'

hairetu[1]='e'

hairetu[2]='k'

hairetu[3]='o'

hairetu[4]='\0'


格納された


文字列データ"neko"の

'n'

'e'

'k'

'o'

'\0'


文字列データ"nyao"が


配列変数

hairetu[0]='n'

hairetu[1]='y'

hairetu[2]='a'

hairetu[3]='o'

hairetu[4]='\0'


と格納されることにより


上書きされ

メモリからデータが

消えてしまっているんじゃないかな?????」


アレサ「ここがポインタ変数さんの可愛らしいところなんですの。


たとえば


次のようなプログラムが実行された場合→」


(EAZY IDECの場合)


#include <stdio.h>


int main(void){


char* hairetu="neko";

char* hairetu="nyao";

char* hairetu="myao";

char* hairetu="syao";

char* hairetu="cyao";

printf("%s\n",hairetu);


return 0;

}


コンパイル結果

cyao



(Visual Studioの場合


次のようにプログラムを記述してください)


#include <stdio.h>


int main(void){


char* hairetu="neko";

hairetu="nyao";

hairetu="myao";

hairetu="syao";

hairetu="cyao";

printf("%s\n",hairetu);


return 0;

}


コンパイル結果

cyao



アレサ「コンパイル結果


cyao


が表示されるのですが


このとき


文字列データ

"neko"

"nyao"

"myao"

"syao"

             すべて🍓🍓🍓


後の文字列データに上書きされることなく🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓


メモリ内に保存されていきます。🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓


つまり


       同じポインタ変数名hairetuを🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓


       つかっているにもかかわらず


文字列データ"neko"に続いて


どんどん


新たな文字列データ


"nyao"

"myao"

"syao"

"cyao"



別べつのメモリに


格納されていくのです。



このとき


1番最後にメモリに格納された🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓



文字列cyaoを格納しているメモリのアドレス🍓🍓🍓🍓🍓🍓🍓


ポインタ変数hairetu🍓🍓🍓🍓🍓🍓🍓


に格納されています。


そして


最後に


文字列データ"cyao"をメモリに格納する

char* hairetu="cyao";

が実行されると


char hairetu[ ]="cyao";の時と同じように


配列変数


hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

が生成されて

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

には

文字データ

'c'

'y'

'a'

'o'

'\0'


hairetu[0]='c'

hairetu[1]='y'

hairetu[2]='a'

hairetu[3]='o'

hairetu[4]='\0'


と格納されています。


そして

ポインタ変数hairetuには


文字列データ"cyao"


を格納しているメモリのアドレス


が格納されているので


printf("%s\n",hairetu);


によって表示される文字列は


cyaoになります。


つまり


1番最後のポインタ変数宣言、初期化の命令文


char* hairetu="cyao";


が実行されることにより


配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

には

hairetu[0]='c'

hairetu[1]='y'

hairetu[2]='a'

hairetu[3]='o'

hairetu[4]='\0'

文字データが格納されています。


そして


ポインタ変数hairetuには


文字列データ"cyao"を格納しているメモリのアドレスが


格納されているので


printf("%s\n",hairetu);


を実行すると


cyao



コマンドプロンプト画面に表示されます。


ですので



それまでにメモリに格納された


文字列データ

"neko"

"nyao"

"myao"

"syao"

printf("%s\n",hairetu);


を実行しても


コマンドプロンプト画面に表示することはできなくなりますし




配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

をもちいて


printf("%c\n",hairetu[0]);

printf("%c\n",hairetu[1]);

printf("%c\n",hairetu[2]);

printf("%c\n",hairetu[3]);

printf("%c\n",hairetu[4]);


を実行しても

コンパイル結果は

c

y

a

o

空白

表示されます


配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

以降の


配列変数

hairetu[5]

hairetu[6]

hairetu[7]

hairetu[8]

hairetu[9]

には何も文字列データが格納されていないので


(実際には\0が格納されています)


配列変数を使っても

文字列データ

"neko"

"nyao"

"myao"

"syao"

コマンドプロンプト画面に表示することはできないのですの」






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

作者を応援しよう!

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

応援したユーザー

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

新規登録で充実の読書を

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

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

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