2016-10-06 3 views
2

私はCプログラミングを初めて勉強しています。悩ましい質問があります。 のは、次のコードを見てみましょう:私はこのコードを実行した場合配列変数がそのアドレスと等しいのはなぜですか?

int main() 
{ 
    int arr[3]={1,2,3}; 
    printf("%d\n", arr); 
    printf("%d", &arr); 
} 

は、それはARRと& ARRの両方に同じ結果を与えます。しかし、なぜarr = & arr? 私はこのトピックに関してかなり多くの答えを見ましたが、どれも私には分かりません。簡単に言えば、配列変数は配列の最初の要素のアドレスを保持しています。たとえば、arrはarr [0]のアドレスを保持しています。たとえばarr = 4340です。次に変数arrをメモリのどこかに格納し、 & arrは値4340を格納するメモリセルのアドレスです。& arr = arrの場合、4340が4340番地に格納されていることがわかります。しかし、4340番地の値は配列の最初の要素の値ですそれは1でなければならない??? 私はこの時点で非常に混乱しており、本当に助けに感謝します。

+1

[comp.lang.c FAQ](http://www.c-faq.com/)のセクション6を読んでください。これは、Cの配列とポインタの間のしばしば混乱する関係の良い説明です(規則1:配列はポインタではありません)。 –

+0

@Keith Thompson:参考になりました!私は間違いなくそれを見ます。 – Nguyen

答えて

4

あなたの混乱は、配列のポインタと同等である必要があります。つまり、配列はポインタではありませんが、いくつかのコンテキストでは配列はポインタへのポインタを崩壊させます。

配列は、最初の要素にアドレスを保持しませんが、基本型の要素の連続したセットです。配列自体のアドレスは、最初の要素のアドレスになります。

ポインタと配列の違いが大きい場所は、その違いを示すsizeof演算子です。 intを仮定すると、4バイトであり、ポインタが8バイトであるあなたが関数にarrを渡す場合sizeof(&arr)は、それが最初の要素へのポインタに減衰その時点で、あなた8

を与えるながら、sizeof(arr)は、あなたに12を与えます。したがって、arr&arrを印刷すると同じ価値が得られます。

つまり、%dの代わりに%pを使用してポインタを印刷すると、未定義の動作が発生する可能性があります。

+0

本当にそれは未定義の動作を引き起こしますか?私はそれが 'sizeof(int)!= sizeof(void *) ' –

+2

@AlejandroDíaz住所は必ずしも数字である必要はありません。たとえば、DOSでは、アドレスは単一の数字ではなく2つの数字です。 – dbush

2

プログラムの動作は、で、定義されていません。です。配列タイプの書式指定子または配列タイプのアドレスとして%dを使用することはできません。その配列の最初の要素の値を取得するには、arr[0]を渡すことができます。

時々arrは、それが関数に渡されたときのように、タイプint*のポインタへ減衰を行います。 arrが、%pに訂正されたフォーマット指定子を持つprintfのパラメータであるという文脈において、&arrに等しいという事実は、ポインタの減衰に起因する。

+0

これは、有効な '%p'を使用したときにも起こります。 –

+0

私の間違い。これは 'arr'がポインタに崩壊するためです。私の修正された答えと@dbushの答えが私より優れているのを見てください。 –

関連する問題