2

2D配列にアクセスするために1つの添え字のみを使用する場合に、Cが行の正しいメモリアドレスを取得する方法を誰かが説明できますか?

例 -

int array2D[2][2] = {1,2,3,4};
printf ( "starting address of row2 = %p" , array2D[1]);

Cで添え字を付けると、実際に行われているのはポインターの追加であるため、1d配列の場合、配列名は要素0を指します。この場合、要素1が必要な場合、コンパイラーは開始アドレス(たとえば4000)を取得します。それに4を追加して(4ビットintと仮定)、返されるのはメモリアドレス4004のアイテムになるようにします。

私の理解では、私の例のように2D配列にデータを入力すると、それらは順番に割り当てられるので、

1
234
アドレス

4000 4004

4008 4012

では、Cは、この場合、array2D [1]が4004ではなく4008を指す必要があることをどのように計算しますか?sizeof()演算子を実行しますか、それともここで基本を誤解しましたか?

前もって感謝します

4

4 に答える 4

3

Cは各行の長さを知っているので、行を見つけるために乗算を行います。

int x[][3] = {{1,2,3},{4,5,6}};

次にプラス&x[1][0]です。&x[0][0]3 * sizeof(int)

そのため、多次元C配列宣言では、最初の次元を除くすべてを指定する必要があります。

于 2012-08-24T15:29:52.503 に答える
0

ポインタ演算は、ポイントされている要素のタイプによって異なります。pタイプへのポインタをT指定すると、タイプp + 1の次の要素Tを指しますが、必ずしも次のバイトを指すとは限りませんp。の場合、;の直後のバイトから始まる、の次のオブジェクトをT指します。の場合、は、の次の10要素の配列を指します。これは、の次の10バイト目から始まります。 charp + 1charppTchar [10]p + 1charpp

の式の型は、 array2dの2要素配列の2要素配列int」です。これは「減衰」して「の2要素配列へのポインタint」またはint (*)[2]1を入力します。したがって、式array2d[1]はとして解釈され*(array2d + 1)ます。はタイプのarray2dオブジェクトを指しているので、次の次の2要素配列を指します。これは。からバイト離れています。 int [2]array2d + 1intarray2d2 * sizeof intarray2d


1.演算子sizeofまたは単項演算子のオペランドである場合&、または宣言内の別の配列を初期化するために使用される文字列リテラルである場合を除き、「N要素配列のT」タイプの式は「ポインタ」タイプの式に変換されます。 to T"とその値は、配列の最初の要素のアドレスになります。

于 2012-08-24T15:52:11.077 に答える
0

これは少し時間がかかるでしょうが、それでも我慢してください。

配列サブスクリプションは単なる省略形です。ポインター型のすべてのコンテキストで(p[N])等しいです(ただし、どちらも無効な式です)。(*(p + N))void*

ここで、が配列型の場合、 ;pのような式でポインタ型に減衰します。(*(p + N))anは、型のポインタ(つまり、int[2][2]へのポインタ)に減衰します。(*)[2]int[2]

ポインタ演算は型を考慮に入れます。char*コンパイラが私たちに何をするかを視覚化するために、物事を変換する必要があります。

T *p;
p[N] equals *(p + N) equals *(T*)((unsigned char*)p + N * sizeof *p)

さて、もし(私Tたちint[2]が上で説明した状況に等しい)なら、それsizeof *psizeof(int[2])、すなわち2 * sizeof(int)

これは、サブスクリプションがいわゆる多次元配列でどのように機能するかです。

于 2012-08-24T15:52:23.647 に答える
0

sizeof(array2D [1])== 8;
array2Dアドレスが4000の場合。
したがって、array2D[1]アドレスは4000+ sizeof(array2D [1])== 4000+8です。

于 2012-08-24T16:08:51.173 に答える