パート1:
配列名は定数です (変更可能な左辺値ではありません)。配列名に値を追加することはできますが、変更することはできません。
式はそれ自体a + 2
を変更しませんが、それを行うと、配列名を変更しようとするのと同じです --lvalue エラー。2 番目の printfの式が間違っています - セマンティック フェーズ エラーの例です。次の言語標準をお読みください。 a
a++
a = a + 1
a++
724変更可能な左辺値とは、配列型を持たず、不完全な型を持たず、const 修飾された型を持たず、構造体または共用体である場合、メンバー (再帰的に任意の含まれているすべての集約または共用体のメンバーまたは要素) を const 修飾された型で使用します。
729 それが sizeof 演算子または単項演算子のオペランドである場合&
、または配列の初期化に使用される文字列リテラルである場合を除き、型「型の配列」を持つ式は型「型へのポインタ」を持つ式に変換されます。配列オブジェクトの最初の要素を指し、左辺値ではありません。
パート2:
ほとんどの式の配列名は、最初の要素のアドレスで減衰することに注意してください (配列名が最初の要素へのポインターに減衰しないいくつかの例外をお読みください。@H 2 CO 3で適切に回答されています)。
その結果はa + 2
、3 番目の要素のアドレス (または index の要素のアドレス2
)になるため、インデックスの値ではなくアドレスa + 2
と同じです。&a[2]
アドレスを印刷するには、次のように、%p
代わりに使用し、%d
アドレスを型キャストvoid*
します。
printf("address (a + 2) = %p , &a[2] = %p", (void*)(a + 2), (void*)(&a[2]));
*
値を出力するには、次のように防御演算子が必要です。
printf("address *(a + 2) = %d , a[2] = %d", *(a + 2), a[2]);
パート 3:
a が 2010 の場所に格納されているとします。最初の printf 関数の出力は 2012 ですか?
いいえ、ポインター演算は整数演算とは異なります。私たちが知っているように、配列名はほとんどの式で最初の要素のアドレスに崩壊します。したがってa + 2
、値は index にある3番目の要素のアドレスです2
。したがって、システムの int サイズが 4 バイトの場合、アドレス値が 2010a + 2
であるという仮定に従って、stat が場所 2018 を指しているとします。a
理解するには、10.2 ポインターと配列を読んでください。ポインター演算とポインター演算。