式ar
は、常に配列オブジェクトを参照し、タイプはint [4]
です。 ar
がsizeof
オペランドまたは単一&
オペレータの場合を除き、配列の最初の要素のアドレスである型int *
の式に置き換えられます( "decay to")。
したがって、起こり
printf("address of ar[0] is %p\n", (void *) ar);
最初のもののような与えられたコードは、タイプint *
と値ポインタ式に表現ar
「崩壊」はvoid *
にキャストされ、&a[0]
と同じであるということですそれが印刷されます。ポインタ値はar
に格納されません。それはar
から計算されます。
このすべてがマシンコードに変換される方法は、コンパイラによって異なります。ここでは(私はlayout.c
という名前のファイルにコードを保存し、次のアセンブリリストを取得するためにgcc -o layout -ansi -pedantic -Wall -Wa,-aldh=layout.lst layout.c
としてそれをコンパイル)Linux上のgccはそれで何をするかです:
GAS LISTING /tmp/fbgo448-tmp.359a6da/files/ccoNessg.s page 1
1 .file "layout.c"
2 .version "01.01"
3 gcc2_compiled.:
4 .text
5 .align 4
6 .globl main
8 main:
9 0000 55 pushl %ebp
10 0001 89E5 movl %esp, %ebp
11 0003 83EC28 subl $40, %esp
12 0006 8D45D8 leal -40(%ebp), %eax
13 0009 8945F4 movl %eax, -12(%ebp)
14 000c B8000000 movl $0, %eax
14 00
15 0011 C9 leave
16 0012 C3 ret
17 .Lfe1:
19 0013 90 .ident "GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.2 2.96-112.7.2)"
表現-40(%ebp)
がar
の最初の要素です。 -12(%ebp)
はptr
です。 12行目は、項目の実効アドレスを-40(%ebp)
に計算し、その値を%eax
に保存します。これは-12(%ebp)
に書き込まれます。
gcc/linuxのコンテキストでは、ar
に関連付けられたアドレスには、最初の要素の値が含まれています。答えは異なるプラットフォームで異なる可能性があることに注意してください。
あなた自身でテストするのはなぜでしょうか? '&ar [0]'と '(int *)ar'を比較してください。 –