sizeofは、配列へのポインターのこの逆参照でどのように機能しますか?


9

ここに私は4つの整数のptr配列へのポインターがarrあります。ptr配列全体を指します。ptr[0]または*ptr配列の最初の要素を指すため、1を追加して配列ptr[0]の2番目の要素のアドレスを取得します。

sizeof(ptr[0])ptr[0]配列の最初の要素へのポイントとして)最初の要素のみのサイズである4バイトではなく、配列全体のサイズが16バイトになる理由を理解できません。

int arr[4] = {0, 1, 2, 3};
int (*ptr)[4] = &arr;
printf("%zd", sizeof(ptr[0])); //output is 16

2行目はいけませんint *ptr = arr;か?これにより、配列の先頭(最初の要素)を指すようになり&arr[0]ます。これはと同等です。
Andreas Wenzel

1
@AndreasWenzel 2行目はいけませんint *ptr = arr;か? 実は違う。 4つの値の完全な配列へのポインタとしてint (*ptr)[4]作成ptrintます。このようなポインタ構文は、真の多次元配列を動的に割り当てるために必要です。ネストされたmalloc()ループで作成され、多次元配列として誤って記述された「2次元配列」は、実際には複数の1次元配列へのポインターの1次元配列です。stackoverflow.com/questions/42094465/…を
Andrew Henle

回答:


6

OP:ptr[0]配列の最初の要素を指します。

タイプの混乱。 ptr[0]配列です。

ptrintの配列4へポインターです。
ptr[0]のように、配列へ*ptrポインタを参照します。
sizeof(ptr[0])配列のサイズです。


を使用するとsizeof(ptr[0])ptr[0]「配列オブジェクトの最初の要素を指す、型が '' pointer to type ''の式」の変換は発生しません。(c11dr§6.3.2.13)。でsizeofptr[0]は配列です。


1
@ Abd-ElrahmanMohamed同意する "しかし、ptr [0] [0]は整数を指すのではなく整数である"。「ptr [0]は配列の最初の要素のアドレスです」は正しくありません。
chux-モニカを

1
@ Abd-ElrahmanMohamedはい、値は同じですがタイプが異なります。PTR [0]は配列型を有し&ptr[0][0]有するint *タイプ
グリーンツリー

1
@chux ptr[0](暗黙的にに変換int *されます)は、最初のint要素のアドレスに評価されます。
グリーンツリー

1
@chux sizeofについて-そうです、私はあなたが言ったことの文脈を誤解しました
Green Tree

1
@ Abd-ElrahmanMohamedそれはしません。 printf("someforamt", ptr[0] , ptr[0]+1)とは異なる何かをしますsizeof(ptr[0])ptr[0]最初のケースでは、inplicit変換を通過します。ではsizeof(ptr[0])、ありptr[0]ません。
chux-モニカを

5

ptrこれはタイプでpointer to an array of 4 int elementsあり、配列タイプはプラットフォームでサイズ16です(sizeof(int)*(要素の数))。

sizeof(ptr [0])を使用すると、配列全体のサイズが16バイトで、最初の要素だけのサイズではなく4バイトになる理由がわかりません

C型システムには配列型があるためです。ここに両方arrあり*ptrます。あなたが持っているとあなたが宣言するもの。ここでsizeof intを取得するには、sizeof(ptr [0] [0])-ここで、ptr [0]は配列に評価されます。


2

int (*ptr)[4] = &arr ;、あなたは、4つの整数の配列へのポインタとARRを指しています。

ptrarr、ダブルポインタのようにを指しています。where toのarr使用方法の要素にアクセスできます。ptr[0][x]x04

だから、sizeof(ptr[0])同じですsizeof(arr)


2

定義により、はとptr[0]同じで*(ptr + 0)あり、はと同じ*ptrです。さらに、ptrで初期化される&arrので、そうで*ptrあり*&arr、それだけarrです。&arrin の中間ストレージは配列の減衰を実行ptrないため、等価性が維持され、型情報が失われないことに注意してください。

これはすべて、追加の落とし穴を避けるために、コンパイル時に計算されることに注意してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.