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);
}
は、エラーになります。
わざわざ実例を挙げていただき本当に
ありがとうございましたっ!
正直いまだに、&chが配列全体を指すという
原理は自分でも納得できていない感はありますが
回答者様の回答を今後何度も見直したりして
徐々に理解していきたいと思っています。
No.4
- 回答日時:
No.3 です。
慌てて書いたら、かなり間違いが……
> 型は、char()[10] (char 10個の配列へのポインタ)
型は、char(*)[100] (char 100個の配列へのポインタ)
> scanf(“%s”,ch[0]);
> の場合と、同じように処理されます。
scanf(“%s”,ch);
の場合と、同じように処理されます。
このくらいか。
No.1
- 回答日時:
>上記の方が間違いであるとするならばうまくいかない場合はどういうときなのでしょうか?
「配列全体のアドレスが、先頭要素のアドレスと同じとは限らない」と言う事です。
例えば「配列を作成すると、配列の先頭に管理用のメモリが4バイト確保され、配列全体のアドレスは管理用メモリの先頭になり、先頭要素のアドレスは配列全体のアドレスの4バイト先になる」と言う処理系があったとします。
その場合「配列の先頭要素のアドレス」の代わりに「配列全体のアドレス」を使用する事は出来ません。
それを間違えば「配列の先頭にある4バイトの管理用メモリが壊されて、致命的なメモリアクセスエラーが起きる」でしょう。
現在、広く一般に使われている処理系では「配列の先頭要素のアドレスと、配列全体のアドレスが、等しくなるようになっている」ので両者は区別が難しいですが「配列の先頭要素のアドレスと、配列全体のアドレスが、等しいと言う保証はどこにもない」と言う事を忘れないようにして下さい(99.999999%は大丈夫ですけどね。無いとは言えない)
回答ありがとうございました。
なかなか難しいですが、とりあえず「先頭要素のアドレスと
配列全体のアドレスがたいていの場合は等しいがそうでないときも
あるので文字全体を指すときは&を使うべきではない」と
理解しておきたいと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語 配列の長さの上限
-
先頭アドレスとは何ですか?
-
C# 配列の変数宣言について。
-
CSVファイルのデータを2次元配...
-
2次元配列を戻り値とする関数?
-
C言語初心者 ポインタについて...
-
配列をEraseしてもメモリが開放...
-
市販のビンゴカードについて
-
なぜ配列は0から始まるのです...
-
複数の選択範囲の行番号を個別...
-
VB2010でのコントロール多次元...
-
VBで構造体の配列を関数に渡す...
-
Functionの戻り値を2次元配列...
-
配列を使わずに、変数名を動的...
-
LGノートPCグラムについて
-
ポインタの配列のコンマについて
-
if文の判定条件に配列
-
配列内の文字間を排他的論理和...
-
配列の参照渡しで型が一致しま...
-
テキストファイルから文字列を...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語 配列の長さの上限
-
配列を使わずに、変数名を動的...
-
配列で格納したものをmsgboxで...
-
C# Listを使わずに2次元配列の...
-
C# 配列の変数宣言について。
-
先頭アドレスとは何ですか?
-
C言語で特定列だけを抽出して配...
-
配列の参照渡しで型が一致しま...
-
VBで構造体の配列を関数に渡す...
-
C++ vectorに配列をプッシュしたい
-
【速いブラインドタッチ】手を...
-
unsigned char配列への入力の仕方
-
配列をEraseしてもメモリが開放...
-
【C言語】配列の中に配列を入れ...
-
ExcelVBAで質問です。離れた二...
-
4勤2休のシフト作成
-
Functionの戻り値を2次元配列...
-
Redimした動的配列はEraseする...
-
配列を含む構造体の初期値について
-
複数の選択範囲の行番号を個別...
おすすめ情報