scanf関数は格納する変数のアドレスに宛てて数値を格納する。

突然ですがここでscanf関数が登場します


scanf関数については


後のエピソードでしっかり学習することになるのですが


なぜか


ソーラー達はここにやってきました。


#include <stdio.h>


int main(void)

{

int a;

scanf("%d",&a);

printf("%d",a);

return 0;

}


(Visual Studioの場合はscanf関数は使えないので


次のプログラムのように


scanf_s関数をおつかいください)


#include <stdio.h>


int main(void)

{

int a;

scanf_s("%d",&a);

printf("%d",a);

return 0;

}


アレサ「000000010100000010010000000.....


上記のプログラムを観察してみますの。


このプログラムをコンパイルすると


コマンドプロンプト画面にアンダーバーが表示されます。


_


👆このような感じです


ここで数値1をキーボードから入力すると


int a;


で作製されたint型の変数aに1が格納されます


そののち

printf("%d",a);

が実行されて


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


1


が表示されます。


int型の変数aに入力したデータが格納されますので


入力するデータは整数値が望ましいといえますの。


実数値1.2345を入力したなら


int型の変数aにあわせて


実数値1.2345の小数点以下の部分は切り捨てられ


int型の変数aには1だけが格納されることになりますの。


ここで


scanf("%d",&a);


の第2引数が変数aのアドレスになっています。


(&aと表記すると


変数aのアドレスをあらわすことができます。


アドレスとはメモリにつけられた番号のことでした)


scanf("%d",a); となっていないのですね。


ソーラーさん。



0011111111110010010000000


scanf("%d",&a);


scanf関数の命令文で


&aつまり変数aのアドレスがつかわれているということは


scanf関数は


int型の変数aのアドレス&aに宛てて数値を格納しているんですね。


0000000011111111111」


(int型の変数aでは


int型なのでメモリの4バイトの格納領域に


aという名前がつけられています。


4バイトの中の


1バイトごとに

4198543

4198544

4198545

4198546

のように

アドレスがついているのですが


変数aのアドレスとは


先頭の

4198543を用いて表されます)




ソーラー 「そうだったんだね。とても簡単なことだったね。


なんでscanf関数をつかって変数に数値を取り込むとき


&(アンドマーク)が出てくるのかと思ったら・・・


実はとっても自然な表現だったんだね。


その変数のアドレス宛に入力数値を格納していたんだね。


それにしても・・・・


たしかに


住所がわからないと宅急便が荷物を配達できないように


アドレスが名づけられてないとそのお部屋(この場合は変数aのお部屋)に


数値を格納できないよね・・・」


アレサ 「00そうですね。00」


ソーラー 「突然ですが ひとまずこのプログラムを使って


実際に


int型の変数aに数値567866を格納してみよう。


#include <stdio.h>

int a;

int main(void)

{

scanf("%d",&a);

printf("%d",a);

return 0;

}


コンパイル結果

567866(と入力すると)

567866(と表示されます)


このプログラムをコンパイルして


コマンドプロンプト画面から


567866を入力すると


変数aに数値567866が格納されます


そのあと


printf関数により


int型の変数aに格納されている数値567866



コマンドプロンプト画面にprintf出力表示されているというわけです。


そのとき


変数aに格納されている数値を表示するために


printf("%d",a);をつかわれています


アレサ 「00000111・・・


printf("%d",a);においては


scanf("%d",&a);とはまた違い


変数aのアドレスを使わずに


直接 変数aを指定して数値を%d出力していますね。」


ソーラー 「うん、


printf("%d",a);


これはこれで自然な表現だと思うな。ここは


なんか


変数aのアドレスを使わないのがぴったりな感じがするね・・・


(天国にいけるC言語入門 シーズン1でも登場した)


%d出力変換指定子が


scanf関数を使って10進数数値を取り込む際につかわれています。


このとき10進数数値は


10進数から2進数と数値変換して


メモリにおくりこまれています。


printf("%d",a);のときは


%d出力変換指定子は


変数aと名前をつけられたメモリ内に格納された


2進数を10進数へと数値変換してprintf出力表示する。


大活躍だね。」


アレサ 「本当 そうですね。


ところで


#include <stdio.h>

int a;

int main(void)

{

scanf("%d",&a);

printf("%d",a);

return 0;

}


このプログラムのように


int a;と


main関数の前にaの変数宣言をおいても


コンパイルできます



01110101010101001010101010101010................


0001010101010010101..........


ここも不思議です。


int a;は


どういう扱いになっているんでしょうか?


int a;

int main も両方とも整数値を格納する変数の型intがついています。


整数値を格納する変数の型intが並んでいるように見えます


この

int a;

int main もおなじ数値を格納するintなのでしょうか??


ソーラー 「


そうだね。おもしろいね。


さあ、どうかな?まあ


ヘキサ構造体であるがゆえに(笑)


これから徐々にわかってきそうだね。・・・。」


楽しみだね。」

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

作者を応援しよう!

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

応援したユーザー

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