プロが教えるわが家の防犯対策術!

&と配列とアドレスの関係性についての質問です。

以下のような処理を書くと、「a」「&a」「&a[0]」は全て同じ
値をさしてしまいます。

「a」と「&a[0]」が同じなのはわかりますが、「&a」も
同じというのは、なぜでしょうか。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
int main(void)
{
 int a[1];

 printf("%d\n",a);
 printf("%d\n",&a);
 printf("%d\n",&a[0]);

 return 0;
}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

A 回答 (3件)

a と &a はデータ型が違う――というのは


既に回答があるとおりでです。

さて、もともと、この場合の、a は、配列名
です。
ですから、&a は、「配列のアドレス」です。

逆に、「式中に現われる型「Tの配列」とい
う左辺値は(3つの例外を除いて)、配列の
最初の要素を指すポインターに意味が格下げ
になる。結果としてできるポインター の型
は「Tへのポインター」となる」
http://www.kouno.jp/home/c_faq/c6.html#0
という決まりがあるので、「配列の名前が書
かれていると、大抵の場合、配列の先頭要素
を指すポインタとして扱われるわけです。

むしろ、a とだけ書いたときに、アドレスが
得られるほうが、「ちょっと変な仕様」であ
るわけです。

ちなみに、上の「3つの例外」のひとつは、
「& の引数になるとき」で、&a の a は、
配列そのものを意味します。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
わかりやすい説明ありがとうございました。

お礼日時:2009/05/19 19:32

>「a」と「&a[0]」が同じなのはわかりますが、「&a」も


>同じというのは、なぜでしょうか。

「a」が「オブジェクトの先頭アドレス」を意味するからです。

「a」について、コンパイラがどういう解釈をしようが「先頭アドレスは1つ」です。

書き方によって「先頭アドレスがコロコロ変わってしまう」としたら、アドレスが信用できません(笑)

以下のように、要素数を「2以上」にしておいてから「+1」してみると、結果が変わってきます。

int main(void)
{
int a[10];

 printf("%p\n",a); //先頭要素へのポインタに格下げ
 printf("%p\n",&a); //配列そのもののポインタ
 printf("%p\n",&a[0]); //先頭要素へのポインタ

 printf("%p\n",a+1); //先頭要素の次、つまりa[1]のポインタ
 printf("%p\n",(&a)+1); //配列そのものの次、つまり配列の最後の要素の次のポインタ
 printf("%p\n",(&a[0])+1); //先頭要素の次、つまりa[1]のポインタ

 return 0;
}
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

わかりやすい例示ありがとうございました。

お礼日時:2009/05/19 19:31

aと&aはデータ型が違いますが先頭アドレスは同じなので同じ値になります


それとポインタの表示には%dではなく%pを使います
aはint*型
&aはint(*)[1]型

インクリメントすると違いがわかります
#include <stdio.h>
int main(void)
{
int a[2];
int *p = a;
int (*q)[2] = &a;

printf("%p\n",p);
printf("%p\n",p+1); // 4増える
printf("%p\n",q);
printf("%p\n",q+1); // 4*2増える

return 0;
}
    • good
    • 0

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