- ベストアンサー
printfとscanfの違いって・・・
ふとした疑問がわいたので、質問させていただきます。 なぜ、scanfの時は scanf("%d",&a)のように アンパサンド&をつけるんでしょうか? 一方、printfだと、prinf("%d",a)のように アンパサンド&はつけません。 どうして、両方とも関数なのに アンパサンドをつける、つけないの区別があるんでしょうか? プログラミングしていて、ふと思ったんですが なぜなんでしょうか・・・?
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
scanfはaという変数のある「場所」に"%d"の型で格納すると言うものです。 一方printfではaという変数の「中身」を"%d"という型で出力すると言うものです。 つまりaと表記した場合はaの「中身」を指すことになり、&aと表記された場合はaという変数のある「場所」を指すことになります。 詳しく言うと今aという変数が10と言う場所に割り当てられているとします。そして中身には5と言う数値が入っていたとします。 この場合aのある「場所」は10となり、「中身」は5となります。 &aと書いた場合は「場所」を表すことになりますので、scanfには10が渡されて、格納したい「場所」を指定しています。10と言う場所はaに割り当てられているのでaに格納されることになります。 もしscanfでaと書いてしまった場合は、5と言う数値が渡されてしまい、本来10という場所にあるaとは無関係な5と言う場所にある何かに格納されてしまいます。 これでは思ったとおりの結果にはならないはずです。 まとめるとアドレスか、中身かといえます。
その他の回答 (3)
- ymmasayan
- ベストアンサー率30% (2593/8599)
この問題はポインタを抜きにしては語れません。 C言語の設計思想は「簡単な記述で何でもできる」です。 scanfやprintfでも「一つの文でどこの場所からでも入出力可能」な設計にしてあります。 このためにはポインタ使用が必須です。 printfでは値だけが必要なので「*p」でポインタ使用が可能です。 これと等価なのは「a」ですね。 ところがscanfでポインタを使うには場所が必要なので「p」でないといけません。 これと等価なのが「&a」なのです。 と言う事で、「a」と「&a」で理解するよりも「*p」と「p」で理解しておく方が応用がきくと思います。 蛇足ですが scanf("%d",a)のような仕様にする事も出来たはずです。 しかし、これではどこの場所にでも読み込めるという機能が実現できませんので、 今のような仕様にしたのだと思います。
お礼
ありがとうございました。 私も、そういう仕様になぜしないんだろうな・・・と 疑問に思っていました。 と、いうより当時の技術じゃこれが精一杯だったのかも。ある本には「C言語は文法の出来が悪い」とか書いてあるし。。。
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
printfは、表示なので、値がわかればいいですが、 scanfは、格納しなければならないので、変数の値ではなく、"場所"が必要になります。 変数の"場所"(アドレス)を求めるためにアドレス演算子&をもちいて変数のアドレスを得ることができます。scanfでは、それを渡しているのです。 蛇足ですが 文字列などの場合 char str[]="String"; などの場合&を付けないで scanf("%s",str);とする場合もありますが、 この場合は、strはアドレス定数といってもともとアドレスを表しているので付けないでよいのです。 そういう場合でも scanf("%s",&str[0]);のようにすることもできます。
お礼
ご回答ありがとうございました。 配列の場合、配列名だけだと 先頭アドレスを表す、と参考書に書いてありました。 変数の場合、アドレスの&をつけるんですね。 こういった区別が必要、ってことがわかりました。 失礼します。
- sunasearch
- ベストアンサー率35% (632/1788)
もう、ポインタは習われましたか? 関数の引数の型が、(int)型と(int *)型の様に異なっているからです。 aは変数aの値そのもの、&aは変数aが保存されているメモリ上のアドレスを表します。 関数が「値」を引数として必要としていれば(int)型で渡し、「アドレス」を要求していれば(int *)型で渡す必要があります。 printf文で表示するのは値なので「値」を渡していて、scanf文では値を入力するためのメモリ上のアドレスがわからないと困るので「アドレス」を渡しているのです。
お礼
ありがとうございました。使う範囲内で、&をつけるつけないを区別していましたが、非常に深みがあることがわかりました。