天国にいけるC言語入門 ヘキサ構造体 ver5.2130
1つのポインタ変数宣言をつかって複数の文字データや文字列データをコンピュータのメモリに簡単に1度に格納する方法はあるのですが複数の数値データを1度に簡単に格納する方法はないのです
ここではポインタ変数をつかってアドレスを格納するのではなく文字や数値データを格納する方法をまなんでみましょう。
1つのポインタ変数宣言をつかって複数の文字データや文字列データをコンピュータのメモリに簡単に1度に格納する方法はあるのですが複数の数値データを1度に簡単に格納する方法はないのです
Visual Studio2019以降のヴァージョンではポインタ変数を使って文字列データをメモリに格納する機能は削除されました
Visual Studioは
今もなお
さらなる改良がくわえつづけられています
ちゃんちゃん
ソーラー「だいぶん ポインタ変数について
理解がすすんだんじゃないかな。
もうおわっちゃうよ。
ここらへんで漫才といこうじゃ・・」
アレサ「はいっそうですね。
すこしだけ ちょちょっと おさらいしてみますか?
まずは
ポインタ変数をつかって文字列データ"apple"をメモリに取り込む場合です。」
ソーラー「おねがいしま~す」
アレサ「
#include <stdio.h>
int main(void){
char* hairetu="apple";/*〇hairetuのポインタ変数宣言,初期化〇*/
printf("%s\n",hairetu);
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]);
return 0;
}
コンパイル結果
apple
a
p
p
l
e
(空白)
続行するには何かキーをおしてください
アレサ「
char* hairetu="apple";
/*🌞hairetuのポインタ変数宣言、初期化*/
が実行されると
自動的に
文字データを収める
char型の配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
hairetu[5]
が生成され
文字列データ"apple"は
char型の配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
hairetu[5]
に
hairetu[0]='a'
hairetu[1]='p'
hairetu[2]='p'
hairetu[3]='l'
hairetu[4]='e'
hairetu[5]='\0'
と取り込まれました。」
☆ ☆ ☆
正確な表現は以下のようになります。
char* hairetu="apple";
/*🌞hairetuのポインタ変数宣言、初期化*/
が実行されると
文字列データ"apple"はメモリに格納されます。
そして[ ]演算子のエピソードでも見てきたように
ポインタ変数hairetuに[ ]演算子を用いた
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
hairetu[5]
を用いて
文字列データ"apple"を格納しているメモリに
アクセスすることができます。
char* hairetu="apple";
によって
作製されたポインタ変数hairetuには
文字列データ"apple"を格納している連続したメモリの先頭のメモリのアドレスが格納されています。
そして
文字列データ"apple"を格納している連続したメモリの先頭のメモリには
文字データ'a'が格納されています。
この状態で
[ ]演算子をポインタ変数hairetuにもちいれば
まず
hairetu[0]は文字データ'a'を
格納しているメモリにアクセスすることができるようになります
ポインタ変数hairetuに文字データ'a'を格納しているメモリのアドレスを代入すると
[ ]演算子をポインタ変数hairetuに用いた
hairetu[0]は
文字データ'a'を格納しているメモリのアドレス番号の付いたメモリに
格納されている文字データ'a'をあらわすようになるのです(笑)
hairetu[1]は
hairetu[0]がアクセスしているメモリの次のメモリに
アクセスします
hairetu[0]がアクセスしているメモリの次のメモリには
文字データ'p'
が格納されているので
hairetu[1]は
文字データ'p'を格納しているメモリにアクセスすることとなります。
そのようにして
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
hairetu[5]
は
それぞれ
文字データ'a'
文字データ'p'
文字データ'p'
文字データ'l'
文字データ'e'
文字データ'\0'
を格納しているメモリにアクセスすることができます。
その結果
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
hairetu[5]
は
'a'
'p'
'p'
'l'
'e'
'\0'
を表すようになります
hairetu[0]='a';
hairetu[1]='p';
hairetu[2]='p';
hairetu[3]='l';
hairetu[4]='e';
hairetu[5]='\0';
が実行されたようにみえます。
solarplexussより
☆ ☆ ☆
ソーラー「そうだった そうだった
なつかしいな
そして文字列データ"apple"をメモリに格納する際は
ナル文字'\0'(空白)が
'a','p','p','l','e'につづいて
char型の配列変数
hairetu[5]に格納されるので
printf("%c\n",hairetu[5]);
が実行されると
コンパイル結果
apple
a
p
p
l
e
(空白)
続行するには何かキーをおしてください
のように
eのあとに空白が表示されるのだったね」
アレサ
「そして 文字列データ"apple"をメモリに取り込む場合と
ただ単に
文字データ'a','p','p','l','e'を1文字ずつメモリに取り込む場合との違い
が
この'\0'を
'a','p','p','l','e'を1文字ずつメモリに取り込んだ
後に格納するということでした。
'\0'が格納されていることにより
コンピュータはappleをひとまとまりの文字列と認識し
printf("%s\n",hairetu);
を実行すると
appleがコマンドプロンプト画面に表示されるというわけです。」
ソーラー「ほんと、
この仕組みよくできているよね。」
アレサ
「では、ではですね。
次のプログラムでは
ポインタ変数hairetuをつかって
文字列データ"123"をメモリにとりこんでみましょう。
数値データ123ではありません。
文字列データ"123"です。
""ダブルクォーテーションで囲まれたデータは
中身が数値であっても文字列データをあらわすようになるのでしたね。
原理的には
ポインタ変数hairetuをつかって
文字列データ"apple"をメモリにとりこむときと全く同じです。」
#include <stdio.h>
int main(void){
char* hairetu="123";/*〇hairetuのポインタ変数宣言,初期化〇*/
printf("%s\n",hairetu);
printf("%c\n",hairetu[0]);
printf("%c\n",hairetu[1]);
printf("%c\n",hairetu[2]);
printf("%c\n",hairetu[3]);
return 0;
}
コンパイル結果
123
1
2
3
(空白)
続行するには何かキーを押して下さい_
アレサ「
このプログラムのように
char*型のポインタ変数宣言、初期化
char* hairetu="123";
がおこなわれた場合
char型の配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
が生成されます。
そして
char型の配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
に
hairetu[0]='1'
hairetu[1]='2'
hairetu[2]='3'
hairetu[3]='\0'
と
文字データ
'1'
'2'
'3'
'\0'
が格納されていきます。
☆ ☆ ☆
正確には
"char型の配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
を用いて
文字データ
'1'
'2'
'3'
'\0'
が
格納されているメモリにアクセスすることができる"
です
☆ ☆ ☆
文字列データ"123"が
文字データ
'1'
'2'
'3'
'\0'
と分割されて
char型の配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
に格納されているわけです
char型の配列変数には半角英数字1文字分の文字データ
や
-128から127までの数値データを格納することが
できますが
文字列データ"123"が
char型の配列変数
hairetu[0]に
hairetu[0]="123";
のように
格納されることはありません。
文字データ'1'、'2'、'3'、'\0'と分割されて
char型の配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
に格納されています。
そして
この文字データ'1'、'2'、'3'、'\0'は
シングルクォーテーションで囲われているので
char型の配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
に文字データとして取り込まれており
数値データとしてとりこまれているわけではありませんですの。
プログラムをよく見ると
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
に格納された
文字データ
'1'、'2'、'3'、'\0'を
以下のようにprintf出力表示する際
printf("%s\n",hairetu);
printf("%c\n",hairetu[0]);
printf("%c\n",hairetu[1]);
printf("%c\n",hairetu[2]);
printf("%c\n",hairetu[3]);
が実行されていますが
数値をprintf出力表示する🐦%d出力変換指定子🐦でなく
文字をprintf出力表示する🐤%c出力変換指定子🐤がつかわれていますね。」
ソーラー「このプログラムのポインタ変数宣言、初期化
char* hairetu="123";
をみればわかるように
123はダブルクォーテーション""で囲まれているんだ
だから
123は数値でなく文字列データとして扱われるんだね。」
アレサ「ではではでは😊
char* hairetu[]={"1","2","3"};
とポインタ変数宣言、初期化をおこなった場合はどうでしょうか?
char* hairetuでなく
char* hairetu[]と記述されているのがポイントですの。
これらの文字データ"1","2","3"は
数値データとしてメモリに格納されるのでしょうか?
文字データとしてメモリに格納されるのでしょうか?
文字列データとしてメモリに格納されるのでしょうか?」
ソーラー「このポインタ変数宣言のタイプではでは😊
今さっきのポインタ変数宣言
char* hairetu="123";
とは ちょ~っとちがうんだった。
けど いっしょかな?
char* hairetu="123";
では
char型の配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
に
hairetu[0]='1'
hairetu[1]='2'
hairetu[2]='3'
hairetu[3]='\0';
と一文字ずつしか文字データを取り込めませんでした。
それが例えば
ポインタ変数宣言
char* hairetu[]={"abcdef","ghijkl","mnopqr"};
を行うと
{}内に格納されている文字列データ
"abcdef"←1
"ghijkl"←2
"mnopqr"←3
の数3
に対応して
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
が生成されます
そして
先のエピソードでもみてきたように
hairetu[0]
hairetu[1]
hairetu[2]
に
hairetu[0]="abcdef";
hairetu[1]="ghijkl";
hairetu[2]="mnopqr";
が実行されて
文字列データ
"abcdef"
"ghijkl"
"mnopqr"
をメモリに格納できるんだったのさ(^_-)-☆
同じ
hairetu[0]
hairetu[1]
hairetu[2]
でも 1文字だけ文字データを取り込めるタイプと
文字列データを取り込めるタイプがあることになるんだね。
詳しく述べると
hairetu[0]='1'
hairetu[1]='2'
hairetu[2]='3'
と文字データを格納することになった
hairetu[0]
hairetu[1]
hairetu[2]
と
hairetu[0]="abcdef";
hairetu[1]="ghijkl";
hairetu[2]="mnopqr";
では
同じ
hairetu[0]
hairetu[1]
hairetu[2]
でも
hairetu[0]='1'
hairetu[1]='2'
hairetu[2]='3'
の
hairetu[0]
hairetu[1]
hairetu[2]
は文字データを格納する
変数の役割を
hairetu[0]="abcdef";
hairetu[1]="ghijkl";
hairetu[2]="mnopqr";
の
hairetu[0]
hairetu[1]
hairetu[2]
は
文字列データ
"abcdef"
"ghijkl"
"mnopqr"
を格納する🍓ポインタ変数🍓の役割を果たしているんだね
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
このエピソードのお話の中では
hairetu[0]
hairetu[1]
hairetu[2]
はポインタ変数なのですね。
solarplexussより
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
hairetu[0]="abcdef";
はポインタ変数hairetu[0]を使って文字列データ"abcdef"を
メモリに格納していることになります。
しかし
hairetu[0]をもちいた
hairetu[0]のchar*型のポインタ変数宣言
char* hairetu[0]="abcdef";
を実行することはできません。」
👆
ちょっと補足です
😊 😊 😊 😊 😊 😊
char* hairetu[]={"abcdef","ghijkl","mnopqr"};
は
char* hairetu[3]={"abcdef","ghijkl","mnopqr"};
と記述して実行することができます
もちろん
char* hairetu[]="abcdef";
も実行することができます
ですが
char* hairetu[0]="abcdef";
実行できないのはなぜ?
と思われる方もおられるかもしれません
実際に
char* hairetu[0]="abcdef";
が記述された命令文を実行してみたいと思います
そのプログラムはこちらです
👇
#include <stdio.h>
int main() {
char* hairetu[0] = "abcdef";
return 0;
}
ビルド実行結果(Visual Studioの場合)
エラー (アクティブ) E0094 配列のサイズは 0 より大きくなければなりません
エラー C2466 サイズが 0 の配列を割り当てまたは宣言しようとしました。
エラー C2440 '初期化中': 'const char [7]' から 'char *[0]' に変換できません。
👆このビルド実行結果をみてもおわかりになられますように
char* hairetu[1]="abcdef";
のように
[ ]の中の要素数が1ならば
ポインタ変数
hairetu[0]が生成され
hairetu[0]="abcdef";
が実行されることになりますが
char* hairetu[0]="abcdef";
のように
[ ]の中の要素数を0にしてしまうと
ポインタ変数が1つも生成されないのです
そのことをコンパイラはビルドエラーを通して指摘しています
char* hairetu[]="abcdef";
なら
右辺の文字列データ"abcdef"にあわせて
自動的に
ポインタ変数
hairetu[0]
が生成されることになります
補足部分は完了です
本文へ 戻ります
😊 😊 😊 😊 😊 😊
お話は元に戻って・・・続きから💖
char* hairetu[]={"abcdef","ghijkl","mnopqr"};
を行うと
ポインタ変数
hairetu[0]
hairetu[1]
hairetu[2]
が生成されることになりますが
このときポインタ変数hairetu[0]に[]演算子を用いた
配列変数
hairetu[0][0]
hairetu[0][1]
hairetu[0][2]
hairetu[0][3]
hairetu[0][4]
hairetu[0][5]
hairetu[0][6]
は
文字列データ"abcdef"を
格納しているメモリにアクセスして
それぞれ
'a'
'b'
'c'
'd'
'e'
'f'
'\n'
を表すことになります
hairetu[0][0]='a'
hairetu[0][1]='b'
hairetu[0][2]='c'
hairetu[0][3]='d'
hairetu[0][4]='e'
hairetu[0][5]='f'
hairetu[0][6]='\n'
が実行されたことになります
このとき
文字データ'a'を格納しているメモリのアドレスを
格納しているポインタ変数は
🍋hairetu[0]🍋
になり
文字列データ
"abcdef"
を格納しているメモリの先頭のアドレスも
🍋hairetu[0]🍋
になります
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
補足
このことは
char* hairetu="abcdef";
を実行して
生成される配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
hairetu[5]
hairetu[6]
に
hairetu[0]='a';
hairetu[1]='b';
hairetu[2]='c';
hairetu[3]='d';
hairetu[4]='e';
hairetu[5]='f';
hairetu[6]='\n';
と
文字データが格納されたとき
文字データ'a'を格納しているメモリのアドレスを格納している
ポインタ変数はhairetuになるのに似ていますね。
hairetuの部分がhairetu[0]になっているというわけです。
solarplexussより
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
ソーラー「
そして
ポインタ変数宣言
char* hairetu[1]="abcdef";
は
2次元配列宣言
char hairetu[1][]="abcdef";
((この記述形式のように[]の中の要素(数値)を記述しない場合は右辺の文字列データを構成する文字データの数にあわせて自動的に[]の中の要素(数値)が決定されることになります)
さきほどの補足説明の通り
char* hairetu[0]="abcdef";
と
char hairetu[0][]="abcdef";
は[]の中の要素数が0のため実行することはできないのでご注意ください))
と
仕組みが良く似ていて
どちらの場合でも
配列変数
hairetu[0][0]
hairetu[0][1]
hairetu[0][2]
hairetu[0][3]
hairetu[0][4]
hairetu[0][5]
hairetu[0][5]
が生成され
配列変数
hairetu[0][0]
hairetu[0][1]
hairetu[0][2]
hairetu[0][3]
hairetu[0][4]
hairetu[0][5]
hairetu[0][5]
には
hairetu[0][0]='a'
hairetu[0][1]='b'
hairetu[0][2]='c'
hairetu[0][3]='d'
hairetu[0][4]='e'
hairetu[0][5]='f'
hairetu[0][5]='\n'
と文字データが格納されることになるんだ
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
上記の仕組みも
char* hairetu="abcdef";
は
char hairetu[]="abcdef";
と
仕組みが良く似ていて
どちらの場合でも
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
hairetu[5]
hairetu[6]
に
'a'
'b'
'c'
'd'
'e'
'f'
'\n'
が代入される
すなわち
hairetu[0]='a'
hairetu[1]='b'
hairetu[2]='c'
hairetu[3]='d'
hairetu[4]='e'
hairetu[5]='f'
hairetu[6]='\n'
が実行されることに等しくなります
もしくは
どちらの場合でも
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
hairetu[5]
hairetu[6]
は
'a'
'b'
'c'
'd'
'e'
'f'
'\n'
を
格納しているメモリにアクセスすることになります
ともいえます
solarplexussより
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
アレサ
「そうですね。ソーラーさん
次のプログラムをご覧ください」
#include <stdio.h>
int main(void){
char* hairetu[]={"abcdef","ghijkl","mnopqr"};
printf("%s\n",hairetu[0]);
printf("%s\n",hairetu[1]);
printf("%s\n",hairetu[2]);
return 0;
}
コンパイル結果
abcdef
ghijkl
mnopqr
アレサ「
文字列データ"abcdef"が
hairetu[0][0]のアドレスを格納しているポインタ変数hairetu[0]を使ってprintf出力表示されています。
文字列データ"ghijkl"が
hairetu[1][0]のアドレスを格納しているポインタ変数hairetu[1]を使ってprintf出力表示されています。
文字列データ"mnopqr"が
hairetu[2][0]のアドレスを格納しているポインタ変数hairetu[2]を使ってprintf出力表示されています。」
アレサ「
まるで
配列
hairetu[0]
hairetu[1]
hairetu[2]
に
それぞれ
文字データ
"abcdef"
"ghijkl"
"mnopqr"
が格納されているようですね。
実際には
hairetu[0]
hairetu[1]
hairetu[2]
は配列でなくポインタ変数であり
ポインタ変数
hairetu[0]
hairetu[1]
hairetu[2]
は
文字データ
"abcdef"
"ghijkl"
"mnopqr"
を格納しているメモリの先頭のメモリのアドレスを格納しています。
ポインタ変数
hairetu[0]
hairetu[1]
hairetu[2]
を使って
メモリに格納されている
文字列データ
"abcdef"
"ghijkl"
"mnopqr"
を
表示するには
printf("%s\n",hairetu[0]);
printf("%s\n",hairetu[1]);
printf("%s\n",hairetu[2]);
と記述します。」
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
配列hairetuを用いて
char hairetu[]="abcdef";
を実行したとき
hairetu[0]='a'
hairetu[1]='b'
hairetu[2]='c'
hairetu[3]='d'
hairetu[4]='e'
hairetu[5]='f'
hairetu[6]='\n'
と文字データが格納されますが
そのとき
文字列abcdefをコマンドプロンプト画面に表示するには
文字列データ"abcdef"を格納している先頭のメモリのアドレスを
格納している
ポインタ変数
hairetuを使って
printf("%s\n",hairetu);
と記述します。
char* hairetu[]={"abcdef","ghijkl","mnopqr"};
を実行したとき
文字列
abcdef
ghijkl
mnopqr
をコマンドプロンプト画面に表示するのに
printf("%s\n",hairetu[0]);
printf("%s\n",hairetu[1]);
printf("%s\n",hairetu[2]);
と記述するのも原理は全く同じです。
文字列abcdefをコマンドプロンプト画面に表示するには
文字列データ"abcdef"を格納している先頭のメモリのアドレスを
格納している
ポインタ変数
hairetu[0]を使って
printf("%s\n",hairetu[0]);
と記述します。
文字列ghijklをコマンドプロンプト画面に表示するには
文字列データ"ghijkl"を格納している先頭のメモリのアドレスを
格納している
ポインタ変数
hairetu[1]を使って
printf("%s\n",hairetu[1]);
と記述します。
文字列mnopqrをコマンドプロンプト画面に表示するには
文字列データ"mnopqr"を格納している先頭のメモリのアドレスを
格納している
ポインタ変数
hairetu[2]を使って
printf("%s\n",hairetu[2]);
と記述します。
solarplexussより
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
アレサ「
このように
文字列データ
"abcdef"
"ghijkl"
"mnopqr"
を
%s出力変換指定子をつかってprintf出力表示する場合は
printf関数の第2引数には
文字列データ"abcdef"を格納している先頭のメモリのアドレスを
格納しているポインタ変数hairetu[0]
文字列データ"ghijkl"を格納している先頭のメモリのアドレスを
格納しているポインタ変数hairetu[1]
文字列データ"mnopqr"を格納している先頭のメモリのアドレスを
格納しているポインタ変数hairetu[2]
を記述します。」
ソーラー「なるほど
%s出力変換指定子をつかって
ポインタ変数の格納しているアドレスのメモリの
格納している
文字データを先頭とした
文字列データを
コマンドプロンプト画面に出力表示する
printf("%s\n",hairetu[0]);
printf("%s\n",hairetu[1]);
printf("%s\n",hairetu[2]);
この表記方法は
よくみかけるね😊」
アレサ「
それではお待たせいたしました。
ポインタ変数宣言
char* hairetu[]={"1","2","3"};
の仕組みをみていきたいのです。
これらの文字列データ"1","2","3"は
数値データとしてメモリに格納されるのでしょうか?
文字データとしてメモリに格納されるのでしょうか?
文字列データとしてメモリに格納されるのでしょうか?」
ソーラー「文字列データ"1","2","3"は・・・
たのむよ~~~😊アレサちゃ~ん」
アレサ
「次のプログラムをご覧ください」
#include <stdio.h>
int main(void){
char* hairetu[]={"1","2","3"};
printf("%s\n",hairetu[0]);
printf("%s\n",hairetu[1]);
printf("%s\n",hairetu[2]);
return 0;
}
コンパイル結果
1
2
3
アレサ「
ここで
char* hairetu[]={"1","2","3"};
によって生成される
hairetu[0]
hairetu[1]
hairetu[2]
は
ポインタ変数となっています。
さきほど登場した
hairetuのchar*型のポインタ変数宣言
char* hairetu="123";
によって作製された
☆char型の配列変数☆
hairetu[0]
hairetu[1]
hairetu[2]
に
hairetu[0]='1';
hairetu[1]='2';
hairetu[2]='3';
と文字データをとりこんだときの
☆char型の配列変数☆
hairetu[0]
hairetu[1]
hairetu[2]
とは
違い
char* hairetu[]={"1","2","3"};
によって生成される
hairetu[0]
hairetu[1]
hairetu[2]
は
ポインタ変数なのです。
char* hairetu="123";
では
char型の配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
は
hairetu[0]='1';
hairetu[1]='2';
hairetu[2]='3';
hairetu[3]='\0';
と
文字データ'1'、'2'、'3'、'\0'を格納していました。
それに対し
char* hairetu[]={"1","2","3"};
が実行されると
hairetu[0]="1";
hairetu[1]="2";
hairetu[2]="3";
が実行されます
つまり
ポインタ変数
hairetu[0]
hairetu[1]
hairetu[2]
を使って
文字列データ"1"、"2"、"3"をメモリに格納しています。
その際
ポインタ変数
hairetu[0]
hairetu[1]
hairetu[2]
に[]演算子を用いた
hairetu[0][0]
hairetu[0][1]
hairetu[1][0]
hairetu[1][1]
hairetu[2][0]
hairetu[2][1]
が生成されており
hairetu[0][0]
hairetu[0][1]
hairetu[1][0]
hairetu[1][1]
hairetu[2][0]
hairetu[2][1]
は
hairetu[0][0]='1'
hairetu[0][1]='\0'
hairetu[1][0]='2'
hairetu[1][1]='\0'
hairetu[2][0]='3'
hairetu[2][1]='\0'
をあらわすことになります
そして
文字列データ"1"、"2"、"3"をprintf出力表示する際
printf("%s\n",hairetu[0]);
printf("%s\n",hairetu[1]);
printf("%s\n",hairetu[2]);
と
printf関数の第1引数には
文字列データをprintf出力表示する
%s出力変換指定子が
printf関数の第2引数には
文字列データ"1"、"2"、"3"を格納している連続したメモリの
先頭のメモリのアドレスを格納しているポインタ変数
hairetu[0]
hairetu[1]
hairetu[2]
が
用いられています。
🍋 🍋 🍋 🍋 🍋 🍋 🍋
よく観察すると
まるで
配列名が
hairetu[0]
hairetu[1]
hairetu[2]
の配列に
文字列データ
"1"
"2"
"3"
が
配列名が
hairetu[0]
の配列変数
hairetu[0][0]
hairetu[0][1]
に
hairetu[0][0]='1';
hairetu[0][1]='\0';
配列名が
hairetu[1]
の配列変数
hairetu[1][0]
hairetu[1][1]
に
hairetu[1][0]='2';
hairetu[1][1]='\0';
配列名が
hairetu[2]
の配列変数
hairetu[2][0]
hairetu[2][1]
に
hairetu[2][0]='3';
hairetu[2][1]='\0';
と
格納されているようにもみえます。
コンパイル結果
1
2
3
だけ見ると
コンピュータのメモリに
数値1,2,3がとりこまれているようにみえますが
このポインタ変数宣言
char* hairetu[]={"1","2","3"};
が行われた場合は
メモリに格納されており
数値データ
1
2
3
がメモリに
とりこまれているわけではないのです。
文字列データ
"1"は'1' と'\0'
"2"は'1' と'\0'
"3"は'1' と'\0'
で構成されています
solarplexussより
🍋 🍋 🍋 🍋 🍋 🍋 🍋
ソーラー「文字列データを
1度のポインタ変数宣言で簡単にとりこむ方法は
文字列データが1つなら
char* hairetu="123";
文字列データが複数なら
char* hairetu[]={"abcdef","ghijkl","mnopqr"};
これできまり!
だね。」
アレサ
「はいっ
以上のように
ポインタ変数を使って文字列データを1度に
コンピュータのメモリに格納する便利な方法には
1つの文字列データ"123"を取り込むメモリに取り込む場合には
char* hairetu="123";
複数の文字列データ
"1","2","3"や
"123","456","789","102020”,”882288”
をメモリに取り込む場合には
char* hairetu[]={"1","2","3"};
char* hairetu[]={"123","456","789","102020","882288"};
の格納パターン
この2つがあるのですね。」
ソーラー「それでは
1度のポインタ変数宣言で
文字列データ"1","2","3"でなく
数値データの1,2,3を😋簡単に😋メモリに格納するにはどうしたらいいんだったけか?」
アレサ「それは・・・」
ソーラー「それは・・・」
アレサ「全く・・・」
ソーラー「そういえば それ、やってなかったっけ?」
アレサ「はいっ 全く・・・」
ソーラー「ま、まあ、いっか
次、次はそれ いってみよ」
アレサ「
では~~
char* hairetu[]のような
ポインタ変数宣言をおこない
生成される
ポインタ変数
hairetu[0]
hairetu[1]
hairetu[2]
を用いて
『1度に』
『簡単に』
数値データ
1
2
3
をメモリにとりこむことはできるのでしょうか?」
ソーラー「ええっとぉ~???
ア、アレサさあ~ん
なんかできそうな感じは・・するけど・・・」
アレサ「ではまず
手始めに
次のようにプログラムを構成し
#include <stdio.h>
int main(void){
int* hairetu={1,2,3};
printf("%s\n",hairetu[0]);
printf("%s\n",hairetu[1]);
printf("%s\n",hairetu[2]);
return 0;
}
1度に簡単に数値データ
1
2
3
を
hairetu[0]=1;
hairetu[1]=2;
hairetu[2]=3;
のように
メモリに格納できるか試してみますの
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
int* hairetu={1,2,3};
(🌞このようなポインタ変数宣言、初期化が実行できるかどうかということですね🌞)
int* hairetu={1,2,3};
を実行すれば
ポインタ変数hairetuに[]演算子を作用させた
hairetu[0]
hairetu[1]
hairetu[2]
に
1
2
3
が代入されるような気がする・・・?
solarplexussより
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
int* hairetu={1,2,3};
を実行すれば
ポインタ変数hairetuに[]演算子を作用させた
hairetu[0]
hairetu[1]
hairetu[2]
に
hairetu[0]=1;
hairetu[1]=2;
hairetu[2]=3;
のようにデータが
格納できれば良いのですが・・・」
ソーラー「それではコンパイルしてみようよ アレサ」
アレサ「はい😊 コンパイル」
#include <stdio.h>
int main(void){
int* hairetu={1,2,3};
printf("%s\n",hairetu[0]);
printf("%s\n",hairetu[1]);
printf("%s\n",hairetu[2]);
return 0;
}
コンパイル結果
EAZY IDECの場合
ファイル「C:/Users/solarplexuss/AppData/Local/EasyIDEC/project/hhhhhhhh/main.c」の
「4行目」で記述エラーを発見しました。
警告
assignment makes pointer from integer without a cast
ファイル「C:/Users/solarplexuss/AppData/Local/EasyIDEC/project/hhhhhhhh/main.c」の
「4行目」で記述エラーを発見しました。
「}」を付け忘れています。
Visual Studioの場合
エラー (アクティブ) E0146 初期化子の値が多すぎます
エラー C4700 初期化されていないローカル変数 'hairetu' が使用されます
アレサ「ソーラーさん
int* hairetu={1,2,3};
のような
ポインタ変数宣言、初期化は実行できないようですの」
ソーラー「あれ?なんかできそうな感じなんだけどなあ~?」
アレサ「ポインタ変数宣言をおこない
数値データを1つだけ
たとえば
数値データ1だけをメモリにとりこむなら
1つの変数宣言
int a=1;
をおこない
その変数aのアドレスを格納するために
1つのポインタ変数宣言
int* hairetu;
を行い→
😊 😊 😊 😊 😊 😊 😊 😊
このように
int*型のポインタ変数宣言
int* hairetu;
をおこなったなら
ポインタ変数hairetuに[]演算子を用いた
配列変数
hairetu[0]
をつかって
メモリに格納されているデータに
アクセスすることができるようになります
(ただし、 hairetuにint型の変数のアドレスが与えられた場合のみです)
たとえば
char* hairetu="abc";
のようにポインタ変数hairetuが
"abc"
で
🍓初期化🍓されると
ポインタ変数hairetuに[]演算子を用いた
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
は
文字データ
'a'
'b'
'c'
'\0'
を格納しているメモリにアクセスすることができるようになります
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
に
文字データ
'a'
'b'
'c'
'\0'
が
hairetu[0]='a'
hairetu[1]='b'
hairetu[2]='c'
hairetu[3]='\0'
と格納されている状態にすることができます
別の言い方をするなら
char* hairetu="abc";
が実行されると
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
が生成されて
hairetu[0]='a';
hairetu[1]='b';
hairetu[2]='c';
hairetu[3]='\0';
が実行されているともいえます。
😊 😊 😊 😊 😊 😊 😊 😊
アレサ「
→
作製された
ポインタ変数hairetuに変数aのアドレス&aを代入し
変数aのアドレス&aのメモリにアクセスすることができるようになった
*hairetuを用いて
*hairetuに1を格納するという方法があります。
数値データ1だけをメモリにとりこむだけなら
ポインタ変数宣言
int* hairetu;
を行って
できないことはありません。
そのときのプログラムは次のようになります。」
#include <stdio.h>
int main(void){
int a;
a=1;
int* hairetu;
hairetu=&a;
printf("%d\n",*hairetu);
return 0;
}
コンパイル結果
1
アレサ「ただ、このプログラムはとっても面白いことが
行われたことになるのです
みなさん
それがわかるかな~~~?」
ソーラー「??プログラムは正確にかけてるようだけど・・・
おもしろいことねえ。
それって僕のギャグが面白いってこと?かな?
ほめてもらえたのかな?」
solarplexuss「 面白いこと?
ポインタ変数hairetuに
数値データ1を格納している変数aのアドレス&aを格納したから
[ ]演算子をポインタ変数hairetuに用いた
hairetu[0]
はアドレス&aの番号の付いたメモリにアクセスして
数値データ1をあらわすようになった
ことかな?
フフフ」
アレサ「このプログラムは
ポインタ変数宣言を行って
数値データ1をコンピュータのメモリに格納するためにつくられました。
そして
メモリに格納された
数値1をコマンドプロンプト画面にprintf出力表示しました。
このプログラムが実行された後は
メモリの節約のため
コンピュータのメモリに格納されていた数値データ1は消去されています」
ソーラー「うん、うん、そのとおり😊」
アレサ 「ポインタ変数宣言をおこない
数値データ1を
メモリに格納したいのでしたね」
ソーラー「そうさ😊」
アレサ
「ソーラーさん
int a;
a=1;
int* hairetu;
hairetu=&a;
ここに秘密がかくれているんですの」
ソーラー
「🐈
int a;
a=1;
int *hairetu;🐈
🐈 hairetu=&a;
どこかにゃ~ん」
アレサ
「ポインタ変数宣言を行い数値データ1を
メモリに格納したい
そのために
int a;
🐈にゃお~ん
a=1;
がおこなわれています。」
ソーラー「にゃにゃ😺」
アレサ「つまり
int a;
🐈にゃおにゃお~ん
a=1;
が行われた時点で
コンピュータのメモリに
数値データ1は格納されているんです
ポインタ変数宣言
int* hairetu;
をおこなうことにより
数値データ1をメモリに格納したのではなくて
ポインタ変数宣言をおこない
数値データを格納する*hairetuを作製しなくとも
すでに
変数aのアドレスのメモリに数値データ1が格納されているのです。」
ソーラー「はっ!!!!!!!!!」
アレサ「はい、それではソーラーさん いつものお言葉の時間です」
ソーラー 「なに、なあぁにぃぃぃぃぃぃぃ~~~~~~~ぃぃぃぃ
ぃぃぃぃぃ~~~~~~~
やっちまったなあああぁぁぁぁぁぁぁあああああああ」
🐤...
アレサ「そこで
このプログラムを
次のように変形します
#include <stdio.h>
int main(void){
int a;
int *hairetu;
hairetu=&a;
*hairetu=1;
/*変数aのアドレス&aの番号をもつメモリに
*hairetuを
つかって数値データ1を格納します*/
printf("%d\n",*hairetu);
return 0;
}
(EAZY IDECの場合)
(Visual Studioの場合)
コンパイル結果
1
これで
ポインタ変数宣言を行い
作製された*hairetuを使って数値データ1をメモリに格納できました」
ソーラー「おおおゅ・・・・
む、娘やぁぁぁぁあ・・・・
ナイスじゃないかぁぁぁぁぁあああんんん」
ソーラー「ところで
ポインタ変数宣言を行わず
ここで
🍅配列宣言🍅int hairetu[]={1,2,3};
をおこなえば
次のプログラムのように
あっさりと
#include <stdio.h>
int main(void){
int hairetu[]={1,2,3};
printf("%d\n",hairetu[0]);
printf("%d\n",hairetu[1]);
printf("%d\n",hairetu[2]);
return 0;
}
コンパイル結果
1
2
3
数値データ1,2,3を1度に
配列に格納することができたんだよねぇ~。
どうしたものかな」
アレサ「そうなんですの」
ソーラー「う~ん、いろいろ試したけど
1つの配列宣言
int hairetu[]={1,2,3};
を行ったら
1
2
3
の3つの複数の数値データが1度に
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
に
hairetu[0]=1;
hairetu[1]=2;
hairetu[2]=3;
と格納されるように
1つのポインタ変数宣言をつかって
1
2
3
の3つの複数の数値データを
メモリに1度にとりこむことはできないんだ~
先程は
int* hairetu={1,2,3};
を実行してみたけど
今度は
ためしに
配列宣言、初期化
int hairetu[]={1,2,3};
を真似て
ポインタ変数宣言、初期化
int* hairetu[]={1,2,3};
をおこなって
プログラムを構成、実行したとしても→」
#include <stdio.h>
int main(void){
int* hairetu[]={1,2,3};/*ここの部分ですね*/
printf("%d\n",hairetu[0]);
printf("%d\n",hairetu[1]);
printf("%d\n",hairetu[2]);
return 0;
}
コンパイル結果は
EAZY IDECの場合
ファイル「C:/Users/solarplexuss/AppData/Local/EasyIDEC/project/hhhhhhhh/main.c」の
「4行目」で記述エラーを発見しました。
警告
assignment makes pointer from integer without a cast
ファイル「C:/Users/solarplexuss/AppData/Local/EasyIDEC/project/hhhhhhhh/main.c」の
「4行目」で記述エラーを発見しました。
警告
assignment makes pointer from integer without a cast
ファイル「C:/Users/solarplexuss/AppData/Local/EasyIDEC/project/hhhhhhhh/main.c」の
「4行目」で記述エラーを発見しました。
警告
assignment makes pointer from integer without a cast
Visual Studioの場合
エラー (アクティブ) E0146 初期化子の値が多すぎます
エラー C2440 '初期化中': 'initializer list' から 'int *' に変換できません。
ソーラー「→
と
コンパイルエラーが表示されます。
int* hairetu[]
により
ポインタ変数
hairetu[0]
hairetu[1]
hairetu[2]
が作製されたとしても
ポインタ変数
hairetu[0]
hairetu[1]
hairetu[2]
は
アドレスを格納することのできる変数であり
数値データを格納することのできる変数ではありません
数値データを格納することのできる
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
ではないので
hairetu[0]=1;
hairetu[1]=2;
hairetu[2]=3;
のように数値データ1,2,3をとりこむことはできないとコンパイラは指摘しています
さらに
今のこのプログラム👇の
#include <stdio.h>
int main(void){
int* hairetu[]={1,2,3};
printf("%d\n",hairetu[0]);/*ここの部分ですね*/
printf("%d\n",hairetu[1]);/*ここの部分ですね*/
printf("%d\n",hairetu[2]);/*ここの部分ですね*/
return 0;
}
%d出力変換指定子を
文字列を出力する%s出力変換指定子におきかえて
次のようにプログラムを書き換えても→」
#include <stdio.h>
int main(void){
int* hairetu[]={1,2,3};
printf("%s\n",hairetu[0]);/*ここの部分ですね*/
printf("%s\n",hairetu[1]);/*ここの部分ですね*/
printf("%s\n",hairetu[2]);/*ここの部分ですね*/
return 0;
}
コンパイル結果
EAZY IDECの場合
ファイル「C:/Users/solarplexuss/AppData/Local/EasyIDEC/project/hhhhhhhh/main.c」の
「4行目」で記述エラーを発見しました。
警告
assignment makes pointer from integer without a cast
ファイル「C:/Users/solarplexuss/AppData/Local/EasyIDEC/project/hhhhhhhh/main.c」の
「4行目」で記述エラーを発見しました。
警告
assignment makes pointer from integer without a cast
ファイル「C:/Users/solarplexuss/AppData/Local/EasyIDEC/project/hhhhhhhh/main.c」の
「4行目」で記述エラーを発見しました。
警告
assignment makes pointer from integer without a cast
Visual Studioの場合
エラー (アクティブ) E0144 型 "int" の値を使用して型 "int *" のエンティティを初期化することはできません
エラー (アクティブ) E0144 型 "int" の値を使用して型 "int *" のエンティティを初期化することはできません
エラー (アクティブ) E0144 型 "int" の値を使用して型 "int *" のエンティティを初期化することはできません
エラー C2440 '初期化中': 'int' から 'int *' に変換できません。
警告 C4477 'printf' : 書式文字列 '%s' には、型 'char *' の引数が必要ですが、可変個引数 1 は型 'int *' です
警告 C4477 'printf' : 書式文字列 '%s' には、型 'char *' の引数が必要ですが、可変個引数 1 は型 'int *' です
警告 C4477 'printf' : 書式文字列 '%s' には、型 'char *' の引数が必要ですが、可変個引数 1 は型 'int *' です
ソーラー「→
とエラー表示がでてきます。
う~ん
hairetu[0]
hairetu[1]
hairetu[2]
はポインタ変数となるので
%d出力変換指定子を
%s出力変換指定子に変更してみたのですが
うまくコンパイルできないね。
👆
このプログラムについてはこのエピソードの最後でお話が続くのでお楽しみに!
では
ど~しても💖
数値データを
ポインタ変数宣言をつかってたくさん取り込みたい方は・・・
どうしたらいいのかということになるよね?よね?
そうだね・・・
手間はかかるけど
取り込みたい数だけ
変数宣言とポインタ変数宣言をおこなえば
いいんじゃないかな。」
アレサ「プログラムをつくってみます・・か😊・・
次のプログラムでは
3つの数値データ1,2,3を
3つの変数宣言と
3つのポインタ変数宣言をつかってメモリにとりこんでいますの。」
#include <stdio.h>
int main(void){
int a;
int b;
int c;
int* pta;
int* ptb;
int* ptc;
pta=&a;
ptb=&b;
ptc=&c;
*pta=1;
*ptb=2;
*ptc=3;
printf("%d\n",*pta);
printf("%d\n",*ptb);
printf("%d\n",*ptc);
return 0;
}
コンパイル結果
(EAZY IDECの場合)
(Visual Studioの場合)
1
2
3
アレサ「このプログラムでは
pta
ptb
ptc
の
ポインタ変数宣言
int* pta;
int* ptb;
int* ptc;
をおこなっています
このように🐤int*型🐤のポインタ変数宣言
int* pta;
int* ptb;
int* ptc;
が行われた場合
ポインタ変数
pta
ptb
ptc
は
🐤整数値🐤を格納しているint型の変数のアドレスを
格納することになります。
ポインタ変数
pta
ptb
ptc
に
整数値を格納するint型の変数a,b,cの
アドレス
&a
&b
&c
が
pta=&a;
ptb=&b;
ptc=&c;
のように
格納されると
*pta
*ptb
*ptc
は
int型の変数aのアドレス&a
int型の変数bのアドレス&b
int型の変数cのアドレス&c
のメモリに格納されている数値データをあらわします
そして
*pta
*ptb
*ptc
に
1
2
3
を
*pta=1;
*ptb=2;
*ptc=3;
と代入すると
int型の変数aのアドレスのメモリに数値データ1を
int型の変数bのアドレスのメモリに数値データ2を
int型の変数cのアドレスのメモリに数値データ3を
格納することができます。
このように
1つのポインタ変数宣言では
数値データ1,2,3を
メモリに格納することはできませんでしたが
3つのポインタ変数宣言を行えば
数値データ1,2,3を
コンピュータのメモリに
格納することができますね。
でも1度に簡単ではありませんの・・・」
ソーラー「ここは
ポインタ変数宣言の面白いところだね。
ポインタ変数宣言をつかって
一番基本的であるだろう
数値データ1,2,3を
1つのポインタ変数宣言,初期化
int* hairetu={1,2,3};
のように記述して
同時に
コンピュータのメモリに格納する方法をC言語の開発者はつくらなかったんだ。
((^_^)/以下のプログラムは実行できません)
#include <stdio.h>
int main(void) {
int* hairetu={1,2,3};
printf("%d\n", hairetu[0]);
printf("%d\n", hairetu[1]);
printf("%d\n", hairetu[2]);
return 0;
}
なんでかな?」
👇
👇
👇
👇
👇
👇
👇
👇
👇
👇
👇
👇
👇
👇
いらっしゃ~い
ポインタ変数宣言をつかって
一番基本的であるだろう
数値データ1,2,3を
1つのポインタ変数宣言,初期化
int* hairetu={1,2,3};
のように記述して
同時に
コンピュータのメモリに格納する方法をC言語の開発者はつくらなかったというよりは
作ることができない
という表現の方が正しいです
どういうことでしょうか?
なぜ
先程のプログラムは実行できなかったのでしょうか?
👇
#include <stdio.h>
int main(void){
int* hairetu[]={1,2,3};
printf("%s\n",hairetu[0]);/*ここの部分ですね*/
printf("%s\n",hairetu[1]);/*ここの部分ですね*/
printf("%s\n",hairetu[2]);/*ここの部分ですね*/
return 0;
}
コンパイル結果
EAZY IDECの場合
ファイル「C:/Users/solarplexuss/AppData/Local/EasyIDEC/project/hhhhhhhh/main.c」の
「4行目」で記述エラーを発見しました。
警告
assignment makes pointer from integer without a cast
ファイル「C:/Users/solarplexuss/AppData/Local/EasyIDEC/project/hhhhhhhh/main.c」の
「4行目」で記述エラーを発見しました。
警告
assignment makes pointer from integer without a cast
ファイル「C:/Users/solarplexuss/AppData/Local/EasyIDEC/project/hhhhhhhh/main.c」の
「4行目」で記述エラーを発見しました。
警告
assignment makes pointer from integer without a cast
Visual Studioの場合
エラー (アクティブ) E0144 型 "int" の値を使用して型 "int *" のエンティティを初期化することはできません
エラー (アクティブ) E0144 型 "int" の値を使用して型 "int *" のエンティティを初期化することはできません
エラー (アクティブ) E0144 型 "int" の値を使用して型 "int *" のエンティティを初期化することはできません
エラー C2440 '初期化中': 'int' から 'int *' に変換できません。
警告 C4477 'printf' : 書式文字列 '%s' には、型 'char *' の引数が必要ですが、可変個引数 1 は型 'int *' です
警告 C4477 'printf' : 書式文字列 '%s' には、型 'char *' の引数が必要ですが、可変個引数 1 は型 'int *' です
警告 C4477 'printf' : 書式文字列 '%s' には、型 'char *' の引数が必要ですが、可変個引数 1 は型 'int *' です
ポインタ変数の配列宣言
int* hairetu[]={1,2,3};
を行ったなら
数値データ1,2,3に合わせて
ポインタ変数が3つ
👇
ポインタ変数
hairetu[0]
hairetu[1]
hairetu[2]
が生成されて
それぞれの
ポインタ変数
hairetu[0]
hairetu[1]
hairetu[2]
には
1
2
3
を格納しているメモリ領域の先頭のメモリのアドレス
が
格納されてもよさそうですね
それができないのは
Visual Studioの場合のビルド実行結果に
その理由が表示されています
👇
エラー (アクティブ) E0144 型 "int" の値を使用して型 "int *" のエンティティを初期化することはできません
エラー (アクティブ) E0144 型 "int" の値を使用して型 "int *" のエンティティを初期化することはできません
エラー (アクティブ) E0144 型 "int" の値を使用して型 "int *" のエンティティを初期化することはできません
エラー C2440 '初期化中': 'int' から 'int *' に変換できません。
警告 C4477 'printf' : 書式文字列 '%s' には、型 'char *' の引数が必要ですが、可変個引数 1 は型 'int *' です
警告 C4477 'printf' : 書式文字列 '%s' には、型 'char *' の引数が必要ですが、可変個引数 1 は型 'int *' です
警告 C4477 'printf' : 書式文字列 '%s' には、型 'char *' の引数が必要ですが、可変個引数 1 は型 'int *' です
👆
エラー (アクティブ) E0144 型 "int" の値を使用して型 "int *" のエンティティを初期化することはできません
と表示されていますね
int *型のエンティティはint型のデータでは初期化できない
int *型のポインタ変数はint型の数値データでは初期化できない
という意味なんです
実は
int* hairetu[];
が実行されることにより生成されるint*型のポインタ変数
hairetu[0]
hairetu[1]
hairetu[2]
は
もちろん
int型の変数のアドレスか
int型の変数のアドレスを格納しているポインタ変数でなければ
初期化することができません
ですので
int* hairetu[]={1,2,3};
でなく
int a = 1;
int b = 2;
int c = 3;
を実行したときの
int型の変数aのアドレス&a
int型の変数bのアドレス&b
int型の変数cのアドレス&c
を
ブロック{}内に記述した
int* hairetu[] = { &a,&b,&c };
なら実行できることになります
さらにその場合は
hairetu[0]
hairetu[1]
hairetu[2]
には
💖アドレス💖
&a
&b
&c
が代入されているので
printf("%s\n",hairetu[0]);/*ここの部分ですね*/
printf("%s\n",hairetu[1]);/*ここの部分ですね*/
printf("%s\n",hairetu[2]);/*ここの部分ですね*/
の
文字列データを出力表示する%s出力変換指定子の部分
を
アドレスデータを出力表示する%p出力変換指定子に変えた
printf("%p\n",hairetu[0]);/*ここの部分ですね*/
printf("%p\n",hairetu[1]);/*ここの部分ですね*/
printf("%p\n",hairetu[2]);/*ここの部分ですね*/
に切り替えて
プログラムを実行する必要があります
そのプログラムはこちらです
👇
#include <stdio.h>
int main(void) {
int a = 1;
int b = 2;
int c = 3;
int* hairetu[] = { &a,&b,&c };
printf("%p\n", hairetu[0]);/*ここの部分ですね*/
printf("%p\n", hairetu[1]);/*ここの部分ですね*/
printf("%p\n", hairetu[2]);/*ここの部分ですね*/
return 0;
}
ビルド実行結果
00F8FBA8
00F8FB9C
00F8FB90
int* hairetu[] = { 1,2,3 };
でなく
int* hairetu[] = { &a,&b,&c };
なら実行できましたね
つまり
int*型の配列宣言、
つまり
int*型のポインタ変数の配列宣言をおこない
複数のポインタ変数を生成することにより
複数の
int型の変数のアドレスデータをメモリに格納できるというわけです」
🌷
🌲
🌷
🌹
🌲
🌲
🌹
🌲🌳
もともと
ポインタ変数を使って
数値データをメモリに格納することはできません
ですから
hairetuのchar*型の配列宣言
char* hairetu[3];
をおこなって
char*型のポインタ変数
hairetu[0]
hairetu[1]
hairetu[2]
を
💖3つ💖
生成したとしても
もちろん
char*型のポインタ変数
hairetu[0]
hairetu[1]
hairetu[2]
をつかって数値データをメモリに格納することはできませんし
また
hairetuのint*型の配列宣言
int* hairetu[3];
をおこなって
int*型のポインタ変数
hairetu[0]
hairetu[1]
hairetu[2]
を
💖3つ💖
生成したとしても
もちろん
int*型のポインタ変数
hairetu[0]
hairetu[1]
hairetu[2]
をつかって数値データをメモリに格納することはできません
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます