アプリ版:「スタンプのみでお礼する」機能のリリースについて

配列とポインタについて、二点教えて下さい。

#include<stdio.h>

int main (void){

int test[5]={10,20,30,40,50};

printf("test[0]の値は%dです¥n",test[0]);
printf("test[0]のアドレスは%pです¥n",&test[0]);
printf("test[0]のサイズは%dバイトです¥n.(int)sizeof(test[0]));


printf("test[0]の値は%dです¥n",*test);
printf("test[0]のアドレスは%pです¥n",test);
printf("test[0]のサイズは%dバイトです¥n.(int)sizeof(test));

return 0;

}

二つ質問がございます。

①[]をつけない配列名でアドレスを取得すると、配列の最初の要素のアドレスと同じアドレスが得られるというのは、
printf("test[0]のアドレスは%pです¥n",test);
の部分で示している事でしょうか?

そうなると、
[]が無いことは分かりますが、

②testの前に&が付いていないのは何故でしょうか?

混乱してきました。教えて頂きたいです。

A 回答 (3件)

配列とポインタとの関係については, 前身である B の仕様をひきずっているのでややこしいです.



まず, 配列の「名前」は「配列全体」というオブジェクトを表します. 例えば
int test[5]={10,20,30,40,50};
の場合「test」は「10, 20, 30, 40, 50 という 5個の int型の要素からなる配列全体」を表します.

そして, この「『配列全体』というオブジェクト」は
・sizeof のオペランド
・アドレスを求める単項演算子 & のオペランド
のどちらでもない場合「その配列の先頭要素のアドレス」に変換されます (ほかにも除外されるケースが存在するがこの 2つを押さえておけば十分).

これを前提として

printf("test[0]のアドレスは%pです¥n",&test[0]);

printf("test[0]のアドレスは%pです¥n",test);
の結果を比較することで「配列の最初の要素のアドレスと同じアドレスが得られる」ことがわかります... 「同じアドレスだからどうした」といわれると (その結果だけでは) なんとも言えませんが.

②上で除外された 2つの場合については「配列全体」がそのままオペランドとして使われます. つまり
・sizeof のオペランドの場合には「配列全体」の大きさが求まる (これはプログラムを動かすとわかるはず)
・単項 & のオペランドの場合には「配列全体」のアドレスが求まる
というふるまいをします. 複数バイトからなるオブジェクトでは「その先頭バイトのアドレスがオブジェクト全体のアドレスとなる」という言語仕様上, アドレス値としては (単項 & をつけた) 「配列全体のアドレス」と (単項 & をつけない) 「配列の先頭要素のアドレス」とは同じ値になります. ただし型は異なるので注意が必要です (たいていの場合は単項 & をつけない方が正しい).

配列の要素を求めるために「[]」をつける場合も上の「除外される場合」には当てはまらないため, 厳密には「一度先頭要素のアドレスに変換される」というルールが適用されます. あと現在の C の規格に従った処理系において「test」と「&test[0]」は必ず一致します>#2.
    • good
    • 0

① そうです。


② 言語仕様です。分かりにくいですが慣れるしかありません。

> []をつけない配列名でアドレスを取得すると、配列の最初の要素のアドレスと同じアドレスが得られる

[]をつけない配列名(test)で得られるのは、配列全体のアドレスです。
配列の最初の要素のアドレスは、&test[0]です。
配列の要素がゼロから順にならんでいるので、結局両者は同じアドレスを示していますが。
もし、配列要素の大きい方から順にデータが並ぶようなシステムがあれば、testと&test[0]は異なるアドレスを示すのかもしれません。
    • good
    • 0

正確な説明ではないかも知れませんが、配列名は「配列の先頭要素を指すポインタ」です。



&test[0] と test+0 は同じ意味です。「+0」は省略できるので、
&test[0] と test は同じ意味です。

書き換えると、
printf("test[0]の値は%dです¥n",test[0]);
printf("test[0]のアドレスは%pです¥n",&test[0]);

printf("test[0]の値は%dです¥n",*(test+0));
printf("test[0]のアドレスは%pです¥n",test+0);


test[1]の方がイメージしやすいかもしれません。
printf("test[1]の値は%dです¥n",test[1]);
printf("test[1]のアドレスは%pです¥n",&test[1]);

printf("test[1]の値は%dです¥n",*(test+1));
printf("test[1]のアドレスは%pです¥n",test+1);

何かヒントになりそうでしょうか
    • good
    • 1

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!