🌞🌞🌞複数の文字列データを1つのポインタ変数宣言を使い同時にメモリに格納してみます その3

てんC「今回は 


1つのポインタ変数宣言を使って複数の文字列データをメモリに格納してみたい


とおもいます。


3つの配列宣言

char str[]="apple";

char ars[]="ringo";

char arr[]="cashewnuts";


3つのポインタ変数宣言

char* str="apple";

char* ars="ringo";

char* arr="cashewnuts";


つかうことによって コンピュータのメモリに取り込んできた


 "apple"、"ringo"、"cashewnuts"の文字列データを



        🌞 一つのポインタ変数宣言 🌞


     🌞char* hairetu[]={"apple","ringo","cashewnuts"}🌞


あるいは


     🌞char* hairetu[3]={"apple","ringo","cashewnuts"}🌞


を行うことにより


まとめてメモリにとりこむことができるのです。


     🌞char* hairetu[]={"apple","ringo","cashewnuts"}🌞



     🌞char* hairetu[3]={"apple","ringo","cashewnuts"}🌞




等しい命令文となっています


     🌞char* hairetu[]={"apple","ringo","cashewnuts"}🌞


と記述すると


{"apple","ringo","cashewnuts"}のなかに記述されている


3つの文字列データ

"apple"

"ringo"

"cashewnuts"

の数3に合わせて


     🌞char* hairetu[]={"apple","ringo","cashewnuts"}🌞


が実行されることになります


😊/



ソーラー「ということは 


いいかえると 


異なる3つの文字列データをコンピュータのメモリにとりこむとき


配列宣言もしくはポインタ変数宣言を3つおこなわなくてもいいんだ」


てんC「はい そうなのです


ですので


3つの配列宣言をおこない


char str[]="apple";

char ars[]="ringo";

char arr[]="cashewnuts";



文字列データ

"apple"

"ringo"

"cashewnuts"


を 


コンピュータのメモリに取り込んだ次のプログラム

👇

#include <iostream>


using namespace std;


int main() {


char str[] = "apple";

char ars[] = "ringo";

char arr[] = "cashewnuts";


cout << str << "\n";

cout << ars << "\n";

cout << arr << "\n";

return 0;


}


ビルド実行結果


apple

ringo

cashewnuts



3つのポインタ変数宣言


char* str="apple";

char* ars="ringo";

char* arr="cashewnuts";

を行い


文字列データ

"apple"

"ringo"

"cashewnuts"



コンピュータのメモリに取り込んだ次のプログラム

👇

#include <iostream>


using namespace std;


int main() {


char* str="apple";

char* ars="ringo";

char* arr="cashewnuts";


cout << str << "\n";

cout << ars << "\n";

cout << arr << "\n";

return 0;


}


ビルド実行結果

apple

ringo

cashewnuts


👆

これらのプログラムは


            1つのポインタ変数宣言



        char* hairetu[]={"apple","ringo","cashewnuts"}

もしくは


        char* hairetu[3]={"apple","ringo","cashewnuts"}

を使うことによって


簡略化されて


次のようにかきかえられます。


#include <iostream>


using namespace std;


int main() {


char* hairetu[] = { "apple","ringo","cashewnuts" };


cout << hairetu[0] << "\n";

cout << hairetu[1] << "\n";

cout << hairetu[2] << "\n";

return 0;


}



ビルド実行結果

apple

ringo

cashewnuts


ソーラー「わおっ だいぶ すっきりしたね。


とりこむ文字列データが100個だったらこの方法は有効だね(^_^)/」


ソーラー「さ~て ここで質問で~す」



てんC「ふふっこのとき


cout << hairetu[0] << "\n";

cout << hairetu[1] << "\n";

cout << hairetu[2] << "\n";



なにか表記法が おかしいと思われませんか

cout << hairetu[0] << "\n";

cout << hairetu[1] << "\n";

cout << hairetu[2] << "\n";


hairetu[0]

hairetu[1]

hairetu[2]

に当たる部分には

ポインタ変数が代入されなければなりません。



hairetu[0]

hairetu[1]

hairetu[2]

配列変数で


ポインタ変数に見えないような気がしますが


ポインタ変数となっています。」


みなさ~ん


🐥 🐧 🐦. . .


今日はどんなお話がでてくるのかな😊


🐥 🐧 🐦. . .


ぞろぞろ・・・


それでは 


ソーラーさん


続きをおねがいします。」


ソーラー「みんな あつまってきたね。


cout << hairetu << "\n";の




            🐥hairetu🐥は




配列hairetuやポインタ変数hairetuをつかって


文字列データが格納されたとき



その文字列データが格納されている連続したメモリの先頭のメモリのアドレスを


格納しているポインタ変数ですね。



同時に


文字列データを格納しているメモリを代表するアドレスでもありました。



☆  ☆  ☆  ☆  ☆  ☆


ちょっとだけ補足しま~す


配列hairetuやポインタ変数hairetuをつかって


文字列データがメモリに格納されたとき


配列変数

hairetu[0]

hairetu[1]

hairetu[2]

が生成され


配列変数

hairetu[0]

hairetu[1]

hairetu[2]

には

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


配列変数

hairetu[0]

には

文字列データの先頭の文字データが格納されています


そして

hairetuは

配列変数

hairetu[0]

のアドレスとなっています


                solarplexussより


☆  ☆  ☆  ☆  ☆  ☆




ですので


文字列データを


cout出力表示するときに



cout << hairetu << "\n";

のように


       ポインタ変数🐥hairetu🐥は 


用いられます。


同様に

ポインタ変数宣言

char* hairetu[]={"apple","ringo","cashewnuts"};

が行われて


文字列データ

"apple"

"ringo"

"cashewnuts"

がメモリに格納されて


cout << hairetu[0] << "\n";

cout << hairetu[1] << "\n";

cout << hairetu[2] << "\n";


が実行されるときの


このときの

                


            🐥hairetu[0]🐥は


文字列データ"apple"を格納している連続したメモリの先頭のメモリのアドレスを格納したポインタ変数

         

       

            🐥hairetu[1]🐥は


文字列データ"ringo"を格納している連続したメモリの先頭のメモリのアドレスを格納したポインタ変数

                 

            🐥hairetu[2]🐥は


文字列データ"cashewnuts"を格納している連続したメモリの先頭のメモリのアドレスを格納したポインタ変数



となっているのです。


つまり


ポインタ変数宣言

char* hairetu[]={"apple","ringo","cashewnuts"};



が実行されたとき


3つのポインタ変数

hairetu[0]

hairetu[1]

hairetu[2]

が生成されています


このとき


hairetu[0]="apple";

hairetu[1]="ringo";

hairetu[2]="cashewnuts";


が実行されることに等しくなります


3つのポインタ変数

hairetu[0]

hairetu[1]

hairetu[2]

文字列データが格納されているようにみえますが


正確には

3つのポインタ変数

hairetu[0]

hairetu[1]

hairetu[2]

には

文字列データ

"apple"

"ringo"

"cashewnuts"


を格納している連続した先頭のメモリのアドレスが格納されています



もうちょっと別の言い方をすれば


実は


char* hairetu[]={"apple","ringo","cashewnuts"};


char* hairetu[3];


hairetu[0]="apple";

hairetu[1]="ringo";

hairetu[2]="cashewnuts";


実行されています


char* hairetu[3];

が実行されると


ポインタ変数

hairetu[0]

hairetu[1]

hairetu[2]

が作製されているような形になるのですね。


______________________________________


ところでVisual Studioでは


hairetu[0]という名前のポインタ変数宣言


char* hairetu[0]="apple";


はビルドできません。



Visual Studioのコンパイラはhairetu[0]を1つのポインタ変数とみなしていません。


Visual Studioのコンパイラは


char* hairetu[0]は


ポインタ変数の配列をつくるものと受け取ってしまいます。


つまり要素数が


char* hairetu[3];のように


3なら


hairetu[0]

hairetu[1]

hairetu[2]


のように


ポインタ変数

の配列


hairetu[0]

hairetu[1]

hairetu[2]

が作製されることになりますが


要素数が0と記述してあるので


ポインタ変数の配列が1つも作製できませんと


ビルドエラーが表示されます

______________________________________



次のプログラムのコンパイル結果をみていただければ


hairetu[0]

hairetu[1]

hairetu[2]

文字列データ

"apple"

"ringo"

”cashewnuts”


格納している連続したメモリの


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


ポインタ変数となっていることが


おわかりになられると思います。




#include <iostream>


using namespace std;


int main() {


char* hairetu[] = { "apple","ringo","cashewnuts" };


cout << hairetu[0] << "\n";

cout << hairetu[1] << "\n";

cout << hairetu[2] << "\n";


cout << &hairetu[0] << "\n";

cout << &hairetu[1] << "\n";

cout << &hairetu[2] << "\n";


return 0;


}


ビルド実行結果


apple

ringo

cashewnuts



ついでに

ポインタ変数

hairetu[0]

hairetu[1]

hairetu[2]

のアドレスも


表示してみたいといます


マックス「??????????


ポインタ変数

hairetu[0]

hairetu[1]

hairetu[2]

のアドレス???


な、なんか微妙い?」


#include <iostream>


using namespace std;


int main() {


char* hairetu[] = { "apple","ringo","cashewnuts" };


cout << hairetu[0] << "\n";

cout << hairetu[1] << "\n";

cout << hairetu[2] << "\n";


cout << &hairetu[0] << "\n";

cout << &hairetu[1] << "\n";

cout << &hairetu[2] << "\n";


return 0;


}



ビルド実行結果


apple

ringo

cashewnuts

006FFD40

006FFD44

006FFD48



ソーラー「ふう、いいビルド実行結果だね


完璧だね😊」



マックス「


ポインタ変数

hairetu[0]

hairetu[1]

hairetu[2]

のアドレスが


006FFD40

006FFD44

006FFD48


なのか?????


"apple"

"ringo"

"cashewnuts"


の文字列データは


それぞれ


6バイト

6バイト

11バイト

のデータ量をもつはずだろう?


hairetu[0]

hairetu[1]

hairetu[2]

のアドレスが


006FFD40

006FFD44

006FFD48


だと

hairetu[0]のアドレスのメモリを先頭とした連続した4バイトのメモリに

6バイト

のデータ量をもつ"apple"


hairetu[1]のアドレスのメモリを先頭とした連続した4バイトのメモリに

6バイト

のデータ量をもつ"ringo"



hairetu[2]のアドレスのメモリを先頭とした連続した4バイトのメモリに

11バイト

のデータ量をもつ"cashewnuts"


が格納されていることになるだろう?


なんかおかしくないか?」


ソーラー「ははあ


そこか😊


ポインタ変数

hairetu[0]

hairetu[1]

hairetu[2]

のアドレスと


ポインタ変数

hairetu[0]

hairetu[1]

hairetu[2]

が格納しているアドレス


はちがうんです」



マックス「ど~いうことお?」


ソーラー「たとえば


char* a="apple";


が実行されると


文字列データ"apple"が連続した6バイトのメモリに格納されます


そのとき


連続した6バイトのメモリの先頭のアドレス

イコール

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


char型のポインタ変数aに格納されることになります


ポインタ変数aは連続した6バイトのメモリの先頭のアドレス


つまり


アドレスというデータを格納している変数というわけです


つまり


ポインタ変数aによってあるメモリに連続した6バイトのメモリの先頭のアドレスデータが格納されているわけです


             😊もちろん😊


そのあるメモリにもアドレス番号がありますが



             😊もちろん😊


そのアドレス番号を先頭とした連続した6バイトのメモリに


文字列データ"apple"が格納されているわけではありませんね



同様に


ポインタ変数

hairetu[0]

hairetu[1]

hairetu[2]


にも


アドレス番号

006FFD40

006FFD44

006FFD48

がついていますが


アドレス006FFD40のメモリを先頭とした連続した6バイトのメモリに

6バイト

のデータ量をもつ"apple"


アドレス006FFD44のメモリを先頭とした連続した6バイトのメモリに

6バイト

のデータ量をもつ"ringo"



アドレス006FFD48のメモリを先頭とした連続した11バイトのメモリに

11バイト

のデータ量をもつ"cashewnuts"


が格納されているわけではありません


ポインタ変数

hairetu[0]

hairetu[1]

hairetu[2]



アドレス番号

00402000

00402006

0040200C


を格納しているとしたなら


アドレス00402000のメモリを先頭とした連続した6バイトのメモリに

6バイト

のデータ量をもつ"apple"


アドレス00402006のメモリを先頭とした連続した6バイトのメモリに

6バイト

のデータ量をもつ"ringo"



アドレス0040200Cのメモリを先頭とした連続した11バイトのメモリに

11バイト

のデータ量をもつ"cashewnuts"


が格納されているというわけなんだね😊」


マックス「🐟うおぉ~ そ~いうことか 感心するな


よくわかったなΣ(・□・;)/」



ソーラー「

cout << hairetu[0] << "\n";

cout << hairetu[1] << "\n";

cout << hairetu[2] << "\n";

が実行されることにより

文字列

apple

ringo

cashewnuts

コマンドプロンプト画面に表示されたね。


つまり

hairetu[0]

hairetu[1]

hairetu[2]

文字列データ

"apple"

"ringo"

”cashewnuts”

格納しているメモリの先頭の

アドレスを格納している


ポインタ変数となっていることがわかりますね。


それはおいておいて


ふだんは


char hairetu[]やchar* hairetuによって生成される


配列変数が


hairetu[0]

hairetu[1]

hairetu[2]


となるんだけど


今の場合のように


ポインタ変数宣言


char *hairetu[]={"apple","ringo","cashewnuts"};


が用いられたプログラムが実行された場合


3つのポインタ変数宣言


char *hairetu[0]="apple";

char *hairetu[1]="ringo";

char *hairetu[2]="cashewnuts";

が行われているような感じになります。


#include <stdio.h>

int main(void){


char *hairetu[]={"apple","ringo","cashewnuts"};


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

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

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


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

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

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


return 0;

}


ソーラー「そっかな😊


んですので


char* hairetu[0]="apple";

char* hairetu[1]="ringo";

char* hairetu[2]="cashewnuts";

により生成される

hairetu[0]

hairetu[1]

hairetu[2]

ただの配列変数でなく


文字列データ

"apple"

"ringo"

"cashewnuts"


を保存しているメモリの先頭のアドレスを格納している


ポインタ変数となっているんだね」


アレサ「つまり


char* hairetu[]={"apple","ringo","cashewnuts"};

では


同時に3つのポインタ変数宣言が


1つのポインタ変数宣言により実行されているのですね。


{"apple","ringo","cashewnuts"}内の文字列データ


の数が3つなのに合わせて


char* hairetu[]={"apple","ringo","cashewnuts"};


が実行されると


ポインタ変数


hairetu[0]

hairetu[1]

hairetu[2]

が作製されているのですね。」



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

作者を応援しよう!

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

応援したユーザー

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

新規登録で充実の読書を

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

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

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