• ベストアンサー

文字列の読み込みに関して

char ch[100]; printf("文字列を入力を入力してください。\n"); scanf("%s",&ch); printf("あなたは%sと入力しましたね。\n",ch); ここでいう&chとは配列全体を指すポインタ それに対して Scanf(“%s”,ch); であるchは配列&ch[0]であり配列chの先頭要素を指すポインタである。 どちらの場合でも表示は同じになります。 ですが、上記の方が間違いであるとするならばうまくいかない 場合はどういうときなのでしょうか? 上記の方は配列全体を指すポインタということですがいまいち イメージがわかないです。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

まず、Cでは、char ch[100]; に対して、 &ch と ch が、「同じ場所」であることは 保証されています。 配列全体のアドレスというのは、実は、 型の相違に関係してきます。 ポインタといえば、単に、変数の番地と 考えられることもありますが、実は、 もとの「型」とのつながりを持っています。 例えば、int *p; は、int へのポインタ です。 これと同じで、 ch だけ指定した場合は、これは、 ・char ch[100] の先頭(つまり、ch[0])  をポイントする ・型は、char * (char へのポインタ) というポインタに、「読み替えられること が多い」ということです。 あくまでも、ch は、配列名ですが、 scanf(“%s”,ch); とした場合などに、 「ch[0] をポイントする char * 型」 のポインタと「見なされる」ということです。 一方、&ch は、 ・char ch[100] の先頭(つまり、ch[0])  をポイントする ・型は、char()[10] (char 10個の配列へのポインタ) となります。 この上で、配列へのポインタは、もとの基本型 へのポインタに暗黙のうちに変換可能ですから、 scanf(“%s”,&ch); (配列へのポインタ) は、 scanf(“%s”,&ch[0]); (要素単独へのポインタ) に変換され、 scanf(“%s”,ch[0]); の場合と、同じように処理されます。 失敗する例というのは、基本型(へのポインタ) から、配列へのポインタに型変換が必要な場合で、 void sub(char (*p)[10]) { } という関数を呼び出す場合に、 int main() { char ch[10]; sub(&ch); } は、OKですが、 int main() { char ch[10]; sub(ch); } は、エラーになります。

rinnshan
質問者

お礼

わざわざ実例を挙げていただき本当に ありがとうございましたっ! 正直いまだに、&chが配列全体を指すという 原理は自分でも納得できていない感はありますが 回答者様の回答を今後何度も見直したりして 徐々に理解していきたいと思っています。

すると、全ての回答が全文表示されます。

その他の回答 (3)

回答No.4

No.3 です。 慌てて書いたら、かなり間違いが…… > 型は、char()[10] (char 10個の配列へのポインタ) 型は、char(*)[100] (char 100個の配列へのポインタ) > scanf(“%s”,ch[0]); > の場合と、同じように処理されます。 scanf(“%s”,ch); の場合と、同じように処理されます。 このくらいか。

すると、全ての回答が全文表示されます。
  • kent_a
  • ベストアンサー率18% (36/199)
回答No.2

scanf("%s",&ch); ここが違う scanf("%s",ch); または scanf("%s",&ch[0]);

rinnshan
質問者

お礼

回答ありがとうございました。 そうですね。そこが違っていますね^^

すると、全ての回答が全文表示されます。
回答No.1

>上記の方が間違いであるとするならばうまくいかない場合はどういうときなのでしょうか? 「配列全体のアドレスが、先頭要素のアドレスと同じとは限らない」と言う事です。 例えば「配列を作成すると、配列の先頭に管理用のメモリが4バイト確保され、配列全体のアドレスは管理用メモリの先頭になり、先頭要素のアドレスは配列全体のアドレスの4バイト先になる」と言う処理系があったとします。 その場合「配列の先頭要素のアドレス」の代わりに「配列全体のアドレス」を使用する事は出来ません。 それを間違えば「配列の先頭にある4バイトの管理用メモリが壊されて、致命的なメモリアクセスエラーが起きる」でしょう。 現在、広く一般に使われている処理系では「配列の先頭要素のアドレスと、配列全体のアドレスが、等しくなるようになっている」ので両者は区別が難しいですが「配列の先頭要素のアドレスと、配列全体のアドレスが、等しいと言う保証はどこにもない」と言う事を忘れないようにして下さい(99.999999%は大丈夫ですけどね。無いとは言えない)

rinnshan
質問者

お礼

回答ありがとうございました。 なかなか難しいですが、とりあえず「先頭要素のアドレスと 配列全体のアドレスがたいていの場合は等しいがそうでないときも あるので文字全体を指すときは&を使うべきではない」と 理解しておきたいと思います。

すると、全ての回答が全文表示されます。

関連するQ&A