天国にいけるC言語入門 ヘキサ構造体 ver2.2126
(Visual Studio2018の場合)配列と違いポインタ変数はポインタ変数名を変更しなくても文字列データを💖どんどん💖メモリに格納することができます
🌞🌞🌞ポインタ変数を使って文字列データをメモリに格納していく場合 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"
は
つまり
つかっているにもかかわらず
文字列データ"neko"に続いて
どんどん
新たな文字列データ
"nyao"
"myao"
"syao"
"cyao"
が
別べつのメモリに
格納されていくのです。
このとき
文字列cyaoを格納している
に格納されています。
そして
最後に
文字列データ"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"
を
コマンドプロンプト画面に表示することはできないのですの」
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます