Sizeof, bir işaretçiyi diziye bu kayıttan çıkarma işlemiyle nasıl çalışır?


9

Burada 4 tamsayı ptrdizisine bir işaretçi var arr. ptrdizinin tamamını gösterir. ptr[0]veya *ptrdizinin ilk öğesini işaret eder, böylece dizinin ptr[0]ikinci öğesinin adresini vermek için 1 eklenir .

Neden kullanarak sizeof(ptr[0])tüm dizinin boyutunu verir, 16 bayt, sadece ilk öğenin boyutunu değil, 4 bayt, ( ptr[0]dizideki ilk öğeye işaret eden gibi ).

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

İkinci satır olmamalı int *ptr = arr;mı? Bu, dizinin başlangıcına (ilk öğesi) eşdeğer olmasını sağlar &arr[0].
Andreas Wenzel

1
@AndreasWenzel İkinci satır olmamalı int *ptr = arr;mı? Aslında hayır. dört değerden oluşan tam bir dizi için bir işaretçi olarak int (*ptr)[4]oluşturur . Gerçek çok boyutlu dizileri dinamik olarak ayırmak için bunun gibi işaretçi sözdizimi gereklidir. İç içe döngülerle oluşturulan ve yanlış olarak çok boyutlu diziler olarak tanımlanan "2 boyutlu diziler" , gerçekte 1-boyutlu dizilere birden çok 1-dizi dizilere işaret eden dizilerdir. Bkz. Stackoverflow.com/questions/42094465/…ptrintmalloc()
Andrew Henle

Yanıtlar:


6

OP: ptr[0]dizideki ilk öğeyi gösterir.

Tip karışıklığı. ptr[0]bir dizidir.

ptrint dizisi 4'ün bir göstergesidir .
ptr[0], işaretçiyi işaretçiyi bir diziye*ptr erteler . dizinin boyutudur.
sizeof(ptr[0])


İle sizeof(ptr[0]), ptr[0]"dizi nesnesinin ilk öğesini işaret eden" yazım işaretçisine "sahip bir ifade" dönüşümü oluşmaz. (c11dr §6.3.2.1 3). İle sizeof, ptr[0]bir dizidir.


1
@ Abd-ElrahmanMohamed Katılıyorum "Ama ptr [0] [0] tamsayıyı göstermeyen bir tam sayıdır". "ptr [0] dizideki ilk öğenin adresidir" doğru değil.
chux - Monica'yı

1
@ Abd-ElrahmanMohammed evet, değerler aynı, ancak tipler farklı. ptr [0] dizi türü vardır ve &ptr[0][0]var int *tip
ağacın

1
@chux ptr[0](örtük olarak dönüştürülmüş int *) ilk int öğesinin adresini değerlendirir.
Green Tree

1
@chux hakkında sizeof - doğru, söylediklerinizin bağlamını yanlış anladım
Green Tree

1
@ Abd-ElrahmanMohamed Değil. printf("someforamt", ptr[0] , ptr[0]+1)farklı bir şey yapar sizeof(ptr[0]). ptr[0]İlk durumda bir inplicit dönüşüm geçer. İle sizeof(ptr[0]), ptr[0]yapmaz.
chux - Monica'yı eski durumuna getir

5

ptrişte türdür pointer to an array of 4 int elementsve dizi türünün platformunuzda 16 boyutu vardır (sizeof (int) * (elemet sayısı)).

Neden sizeof (ptr [0]) kullanmanın sadece ilk elemanın 4 bayt boyutunu değil tüm dizinin 16 bayt boyutunu verdiğini anlayamıyorum

çünkü C tipi sistemde dizi türleri vardır. İşte hem arrve *ptro vardır. Sahip olduğunuzu beyan ettiğiniz şey. Burada sizeof int almak için sizeof (ptr [0] [0]) - burada ptr [0] diziyi değerlendirir.


2

ile int (*ptr)[4] = &arr ;bir dört sayı dizisi için işaretçi ve arr işaret var.

ptrşimdi arrçift ​​gösterici gibi işaret ediyor . Biz unsurlarını erişebilir arrkullanarak ptr[0][x]nerede xolabilir 0için 4.

Yani sizeof(ptr[0])aynısizeof(arr)


2

Tanım ptr[0]olarak *(ptr + 0), sırayla aynıdır *ptr. Ayrıca, ptrbaşlatılır &arr, böylece *ptrolduğunu *&arrve bu sadece bir arr. Ara depolama bu Not &arrolarak ptryok değildir eşdeğerlik korunarak ve herhangi bir tip bilgiler kaybolur, böylece herhangi bir dizisi çürüme gerçekleştirin.

Tüm bunların, sadece bu ek tuzaklardan kaçınmak için derleme zamanında hesaplandığını unutmayın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.