2012-03-09 8 views
0

あなたは、ARラベルに関連付けられたアドレスは、配列の最初の要素のをベースアドレスを保持します。このCプログラムメモリは実際にC配列をどのように探しますか?

int main() { 
    int *ptr; 
    int ar[4]; 
    ptr = ar; 
    return 0; 
} 

を持っているか、それが最初の要素自体を開催すると言いますか?その場合は、2番目の場合 ptr = ar; arはそのアドレスにあるものとは対照的にそのアドレスを評価しなければなりません...そうですか?

私はそれがアドレスを保持するこの

+0

あなた自身でテストするのはなぜでしょうか? '&ar [0]'と '(int *)ar'を比較してください。 –

答えて

0

上の任意の入力をお願い申し上げます。最初の要素にアクセスするには、arr [0]またはptr [0]を使用します。

3

arは、ポインタとは異なる配列です。

しかし、ほとんどの場合(ptrに割り当てるなど)、は、を減衰させてポインタ、つまり配列の最初の要素のアドレスになります。

+0

配列の値は、メソッドの他のローカル変数と同様にスタック上にありますか? – eay444

+0

@ user1259909:まあ、それはコンパイラの責任です。ローカル配列は他のローカル変数と同じように動作すると言う方が安全です。 –

0

アレイ名の値は、配列の最初の要素のアドレスです。

0

arは、常に配列オブジェクトを参照し、タイプはint [4]です。 arsizeofオペランドまたは単一&オペレータの場合を除き、配列の最初の要素のアドレスである型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に関連付けられたアドレスには、最初の要素の値が含まれています。答えは異なるプラットフォームで異なる可能性があることに注意してください。

関連する問題