Visual Studioの改定によりVisual Studio2019以降のヴァージョンではポインタ変数を使ってメモリに文字列データを格納することはできません

🌞🌞🌞char* p="abc";を実行したのち [ ]演算子をポインタ変数pに作用させ作製した配列変数p[0]はポインタ変数pの格納しているアドレスのメモリに格納されているデータ'a'を表します。

ソーラー「今日は[ ]演算子の仕組みについてしらべてみよう。」


ソーラー「[ ]演算子はsubscript operator(添字演算子)


とよばれています。」


てんC「ソーラーさん


[ ]演算子ってどこかでみたことが


あるような気がするのですが・・・・]


ソーラー「そう?


みたことがある?


あったかな~


う~ん 


う~~


???


きのせいか?





とりあえず次のプログラムをご覧ください」



#include <iostream>


using namespace std;


int main() {


char* p = "abc";


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

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

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

cout<<p[3]<<"\n";

cout<<p<<"\n";


return 0;


}


ビルド実行結果


a

b

c

(空白)

abc


ソーラー「さて


このプログラムで何がおこなわれているかわかるかな?


char* p = "abc";

char* pにより


char型の

ポインタ変数pが生成されるのがわかります。


ですが


なぜか


ポインタ変数pが


文字列データ "abc"によって初期化されている・・・・・??????????


な、なんで?????


ポインタ変数ってアドレスを格納する変数なんでしょう?


文字列データを格納できるはずがない


って思った方がおられるのではないかな?」


てんC「char* p = "abc";


ですね。(´▽`*)


char* p = "abc";


が実行されると


文字列データ "abc"はメモリに格納されます。


そのとき


文字列データ "abc"が格納されているメモリの先頭のアドレスが


ポインタ変数pに格納されています




ソーラー「ははあ なるほどお


つまり


char* p = "abc";


が実行されると


作製されるポインタ変数pに


文字列データ "abc"が格納されているメモリの先頭のアドレスが


代入されて初期化されているんだね。


ポインタ変数pに


文字列データ"abc"そのものが格納されているわけではないんだね。」



てんC「はいっ そうなんです。


char* p = "abc";


が実行されると


文字列データ "abc"は


メモリに格納されますが


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


ポインタ変数pに格納されています。



その先頭のアドレスを仮に00DA7BDCとすると



文字列データ "abc"は


アドレス00DA7BDCのアドレスの付いたメモリを先頭として


順にメモリに格納されるのですが


具体的には


00DA7BDCのアドレス番号の付いたメモリには文字データ'a'

00DA7BDDのアドレス番号の付いたメモリには文字データ'b'

00DA7BDEのアドレス番号の付いたメモリには文字データ'b'

00DA7BDFのアドレス番号の付いたメモリには文字データ'\0'


のように


文字列データ"abc"は分割されて順番にメモリに格納されています。


ところで


00DA7BDCのアドレス番号の付いたメモリには文字データ'a'


が格納されているのですが


文字データ'a'をcout出力表示したいときは


cout<<*p<<"\n";


を実行すればよいことになるのです。


そのプログラムは次のようになります。


#include <iostream>


using namespace std;


int main() {


char* p = "abc";


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

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

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

cout << p[3] << "\n";

cout << *p << "\n";


return 0;


}


ビルド実行結果


a

b

c

(空白)

a  👈aが表示されました



てんC「cout << *p << "\n";


がポイントなんですの」


ソーラー「はは わかった(^_-)-☆


まず


ポインタ変数pは


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


00DA7BDCを格納しており


00DA7BDCのアドレス番号の付いたメモリには


文字データ'a'が格納されているので


*pはポインタ変数pが格納しているアドレス00DA7BDCの付いたメモリに


格納されているデータを


この場合


文字データ'a'を表すことになるんだね」




てんC「そうなんです😊


素晴らしい解答っですね」


ソーラー「へへ そう?


では


お待たせいたしました。




次はいよいよ


添字演算子[ ]の説明だね。


#include <iostream>


using namespace std;


int main() {


char* p = "abc";



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

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

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

cout << p[3] << "\n";

cout << p << "\n";


return 0;


}


ビルド実行結果


a

b

c

(空白)

abc



ソーラー「今


ポインタ変数pにはアドレス00DA7BDCが格納されているとします。


このとき


ポインタ変数pに


添字演算子[]


をつけて


p[0]

p[1]

p[2]

p[3]

とした場合


p[0]は00DA7BDCのアドレス番号の付いたメモリに格納されている


文字データ'a'を表すことができるんだよ。


そして


p[1]は00DA7BDDのアドレス番号の付いたメモリに格納されている


文字データ'b'を表すことができ


p[2]は00DA7BDEのアドレス番号の付いたメモリに格納されている


文字データ'c'を表すことができるんだ。


p[3]は00DA7BDFのアドレス番号の付いたメモリに格納されている


文字データ'\0'を表すことができるんだ。



なので


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

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

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

cout<<p[3]<<"\n";


が実行されると


ビルド実行結果


a

b

c

(空白)

が表示されるんだね。」



てんC「ソーラーさん つまり


            char p[4]="abc";


のように


       配列を使って文字列データ"abc"をメモリに格納しているわけでもないのに



           char *p = "abc";


を実行して


       文字列データ"abc"がメモリに格納された場合💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖


文字データ'a'の格納されたメモリ

文字データ'b'の格納されたメモリ

文字データ'c'の格納されたメモリ

文字データ'\0'の格納されたメモリ


ポインタ変数pに添字演算子を付けた


配列変数


p[0]

p[1]

p[2]

p[3]

をつかって


アクセスし


配列変数


p[0]

p[1]

p[2]

p[3]


文字データ'a'

文字データ'b'

文字データ'c'

文字データ'\0'

をあらわすことができるというわけなのですね。」



ソーラー「ところで


配列変数

p[0]

p[1]

p[2]

p[3]

のアドレスを格納しているポインタ変数は

p

p+1

p+2

p+3

となっています


ですので


*p

*(p+1)

*(p+2)

*(p+3)


p[0]

p[1]

p[2]

p[3]

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


'a'

'b'

'c'

'\0'

をあらわすことになります


ですので



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

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

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

cout << p[3] << "\n";

の代わりに



cout << *p<< "\n";

cout << *(p+1) << "\n";

cout << *(p+2)<< "\n";

cout << *(p+3)<< "\n";

を実行しても


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


a

b

c

(空白)

が表示されることになります」


その時のプログラムはこちらです

👇

#include <iostream>


using namespace std;


int main() {



char* p = "abc";


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

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

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

cout << p[3] << "\n";


cout << *p<< "\n";

cout << *(p+1) << "\n";

cout << *(p+2)<< "\n";

cout << *(p+3)<< "\n";


return 0;


}


コンパイル結果

a

b

c

(空白)

a

b

c

(空白)


ソーラー「


           🌞配列pを用いて🌞


          char p[4]="abc";

           

を実行し


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


配列変数

p[0]

p[1]

p[2]

p[3]

のアドレスを格納しているポインタ変数は


p

p+1

p+2

p+3

となりましたね


同様に



         🌞ポインタ変数pを用いて🌞



文字列データ"abc"をメモリに格納する場合も


p[0]

p[1]

p[2]

p[3]

のアドレスを格納しているポインタ変数は


p

p+1

p+2

p+3

となるんですね」

























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

作者を応援しよう!

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

応援したユーザー

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

新規登録で充実の読書を

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

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

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