重複の可能性:
C:配列のアドレスがその値と等しいのはなぜですか?
GCC 4.4.1でテストしたところ、が見つかり&a=a
ました。理解できません。&a
配列のアドレスを格納するアドレスである必要があると思います。同じにすることはできません。誰かが私に良い説明をしてくれませんか?どうもありがとう。
重複の可能性:
C:配列のアドレスがその値と等しいのはなぜですか?
GCC 4.4.1でテストしたところ、が見つかり&a=a
ました。理解できません。&a
配列のアドレスを格納するアドレスである必要があると思います。同じにすることはできません。誰かが私に良い説明をしてくれませんか?どうもありがとう。
配列はメモリ内のオブジェクトです。住所とサイズがあります。また、特定のコンテキストでは、配列が最初の要素へのポインターに減衰することも事実です。したがって、数値的には、との両方a
が&a
ポインタ値として比較される場合、両方がメモリ内の同じアドレスを指しているため、それらは等しいと比較されます。ただし、データ型は異なります。特定のコンテキストでは、a
タイプint[4]
( "array 4 of int
")またはint*
( "pointer to ")がありますが、常にタイプ( "pointer to array 4 of ")があります。int
&a
int (*)[4]
int
&a points here
|
V
+------+------+------+------+
| a[0] | a[1] | a[2] | a[3] | sizeof(a) == 16
+------+------+------+------+
^
|
&a[0] also points here
In certain contexts, 'a' means &a[0]
したがって、(void *)a == (void *)&a
。
a
また、とは異なるデータ型を&a
指しているため(特に、指し示している型のサイズが異なるため)、ポインター演算を実行すると異なる結果が得られる ことにも注意してください。a+1
は(1つの値だけ&a[1]
進む)を指しますが、は、1つの「配列4の」単位だけ進むため、で配列の終わりを過ぎたところを指します。int
&a+1
&a[4]
int
&a+1 points here
|
V
+------+------+------+------+
| a[0] | a[1] | a[2] | a[3] |
+------+------+------+------+
^
|
a+1 points here
a
がとして宣言されている場合int a[4]
、&a
はタイプint *[4]
(4の配列へのpoointer int
)のポインタです。
ほとんどの式のコンテキストで使用される場合a
、の最初の要素へのポインタに評価されa
、タイプはint*
。です。式は。とまったく同じ&a[0]
です。これは、6.3.2.1 / 3「左辺値、配列、および関数指定子」のC99標準で必要です。
sizeof演算子またはunary&演算子のオペランドである場合、または配列を初期化するために使用される文字列リテラルである場合を除き、「型の配列」型の式は、「ポインタ型」の型の式に変換されます。配列オブジェクトの最初の要素を指し、左辺値ではない''と入力します。
これは一般に、ポインタへの減衰として知られています。a
あなたはそれが「ポインタに崩壊する」と言われているのを聞くでしょう。
したがって、配列の最初の要素は、定義上、配列自体と同じアドレスを持ちます。したがって、&a
とa
には異なるタイプがありますが、それらは同じポインタ値を持っています。
&a
配列の最初の要素のアドレスを指します(つまりa[0]
)。
a
配列のアドレスを保持します。
また、配列(ie)のアドレスは、配列(ie a
)の最初の項目のアドレスと同じ&a
です。
a
は配列です。
&a
配列のアドレスです。
ほとんどのコンテキストでa
は、式で使用されると、配列の最初の要素のアドレスに評価されます。もちろん、これは配列のアドレスと同じアドレスですが、タイプが異なります。&a
はそれらのコンテキストの1つではありませんがa
、比較のRHSにはあります。
同じ値であるがタイプが異なる2つのものの別の例については、それを考慮して(int)1 == (char)1
ください(int)1 == (float)1
。数値が同じであるため、比較は同じですが、タイプが異なるため、すべての目的で同じように動作するわけではありません。
「It」は、心配する資格のある場所に配列のアドレスを格納しません。a
が自動変数の場合、コンパイラはスタックポインタからのオフセットが何であるかを「認識」します。指示がない限り、コンパイラa
は必ずしもa
どこかのアドレスを格納するわけではありません。グローバル変数の場合、そのアドレスはどこかのシンボルテーブルに格納されている可能性がありますが、プログラムはシンボルテーブルのその場所に直接アクセスしません。
int a[4];
a
の配列4ですint
。そのタイプ名はint [4]
です。
&a
の配列4へのポインタですint
。そのタイプ名はint (*)[4]
です。
Cでは式が無効であることに注意してください&a = a
。代入演算子の左側のオペランドは変更可能な左辺値である必要がありますが、&
演算子の結果が左辺値になることはありません。
はaddress of the array
に等しい address of the first item in the array
。