ขนาดของการทำงานกับ dereferencing ตัวชี้ไปยังอาร์เรย์นี้ได้อย่างไร


9

ที่นี่ฉันมีตัวชี้ptrไปยังอาร์เรย์arrของจำนวนเต็ม 4 ตัว ptrชี้ไปที่อาร์เรย์ทั้งหมด ptr[0]หรือ*ptrชี้ไปที่องค์ประกอบแรกของอาร์เรย์ดังนั้นการเพิ่ม 1 เพื่อptr[0]ให้ที่อยู่ขององค์ประกอบที่สองของอาร์เรย์

ฉันไม่เข้าใจว่าทำไมการใช้sizeof(ptr[0])ให้ขนาดของทั้งอาร์เรย์ 16 ไบต์ไม่ใช่ขนาดขององค์ประกอบแรกเท่านั้น 4 ไบต์ (ตามที่ptr[0]ชี้ไปที่องค์ประกอบแรกในอาร์เรย์)

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

บรรทัดที่สองไม่ควรเป็นint *ptr = arr;หรือ ที่จะทำให้มันชี้ไปที่จุดเริ่มต้น (องค์ประกอบแรกของ) &arr[0]อาร์เรย์ซึ่งเทียบเท่ากับ
Andreas Wenzel

1
@AndreasWenzel ไม่ควรบรรทัดที่สองint *ptr = arr;? จริงๆแล้วไม่มี int (*ptr)[4]สร้างptrเป็นตัวชี้ไปยังอาร์เรย์ทั้งสี่intค่า ไวยากรณ์ของตัวชี้แบบนั้นมีความจำเป็นในการจัดสรรอาร์เรย์จริงหลายมิติ "อาร์เรย์ 2 มิติ" ที่สร้างขึ้นด้วยmalloc()ลูปซ้อนกันและอธิบายอย่างผิด ๆ ว่าอาร์เรย์หลายมิตินั้นเป็นอาร์เรย์พอยน์เตอร์ 1-d ไปจนถึงอาร์เรย์ 1-d หลายตัว ดูstackoverflow.com/questions/42094465/…
Andrew Henle

คำตอบ:


6

OP: ptr[0]ชี้ไปที่องค์ประกอบแรกในอาร์เรย์

พิมพ์ความสับสน ptr[0]เป็นอาร์เรย์

ptr เป็นตัวชี้ไปยังอาร์เรย์ที่ 4 ของ int
ptr[0]เช่น*ptrdeferences ตัวชี้ไปยังอาร์เรย์
sizeof(ptr[0])คือขนาดของอาเรย์


ด้วยsizeof(ptr[0]), ptr[0]ไม่ก่อให้เกิด "การแสดงออกที่มีประเภท '' ชี้การพิมพ์ '' ที่ชี้ไปยังองค์ประกอบเบื้องต้นของวัตถุอาร์เรย์" แปลง (c11dr §6.3.2.1 3) ด้วยsizeof, ptr[0]เป็นอาร์เรย์


1
@ Abd-ElrahmanMohamed เห็นด้วย "แต่ ptr [0] [0] เป็นจำนวนเต็มไม่ใช่ชี้ไปที่จำนวนเต็ม" "ptr [0] คือที่อยู่ขององค์ประกอบแรกในอาร์เรย์" ไม่เป็นจริง
chux - Reinstate Monica

1
@ Abd-ElrahmanMohamed ใช่ค่าเหมือนกัน แต่ประเภทนั้นแตกต่างกัน ptr [0] มีประเภทอาเรย์และ&ptr[0][0]มีint *ประเภท
กรีนทรี

1
@chux ptr[0](แปลงโดยปริยายint *) จะประเมินที่อยู่ขององค์ประกอบ int แรก
Green Tree

1
@ chux เกี่ยวกับ sizeof - ใช่ฉันเข้าใจบริบทของสิ่งที่คุณพูด
Green Tree

1
@ Abd-ElrahmanMohamed นั่นไม่ได้ ทำอะไรบางอย่างที่แตกต่างกว่าprintf("someforamt", ptr[0] , ptr[0]+1) ในกรณีแรกผ่านไปแปลง inplicit ด้วย, ไม่ได้ sizeof(ptr[0])ptr[0]sizeof(ptr[0])ptr[0]
chux - Reinstate Monica

5

ptrนี่คือประเภทpointer to an array of 4 int elementsและประเภทอาร์เรย์มีขนาด 16 บนแพลตฟอร์มของคุณ (sizeof (int) * (จำนวน elemetns)

ฉันไม่เข้าใจว่าทำไมการใช้ sizeof (ptr [0]) ให้ขนาดของทั้งอาร์เรย์ 16 ไบต์ไม่ใช่ขนาดขององค์ประกอบแรกเท่านั้น 4 ไบต์

เนื่องจากระบบประเภท C มีประเภทอาร์เรย์ ที่นี่ทั้งคู่arrและ*ptrมีมัน สิ่งที่คุณประกาศว่าคุณมี ในการรับขนาดของ int ที่นี่คุณควรเลือก sizeof (ptr [0] [0]) - โดยที่ ptr [0] หาค่าอาร์เรย์


2

ด้วยint (*ptr)[4] = &arr ;คุณมีตัวชี้ไปยังอาร์เรย์ของจำนวนเต็มสี่ตัวและชี้ไปที่ arr

ptrกำลังชี้ไปที่arrเหมือนตัวชี้ดับเบิล เราสามารถเข้าถึงองค์ประกอบของการarrใช้ptr[0][x]ที่xอาจจะไป04

ดังนั้น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.