เพื่อทำความเข้าใจกับแฮ็คนี้ก่อนอื่นคุณต้องเข้าใจความแตกต่างของตัวชี้กล่าวคือจะเกิดอะไรขึ้นเมื่อตัวชี้สองตัวที่ชี้ไปยังองค์ประกอบของอาร์เรย์เดียวกันถูกลบออก
เมื่อตัวชี้ตัวหนึ่งถูกลบออกจากอีกตัวหนึ่งผลลัพธ์คือระยะทาง (วัดในองค์ประกอบอาร์เรย์) ระหว่างตัวชี้ ดังนั้นถ้าp
จุดไปa[i]
และq
จุดที่จะต้องa[j]
แล้วจะมีค่าเท่ากับ p - q
i - j
C11: 6.5.6 ตัวดำเนินการเพิ่มเติม (p9):
เมื่อมีการลบพอยน์เตอร์สองตัวทั้งสองจะชี้ไปที่องค์ประกอบของอ็อบเจ็กต์อาร์เรย์เดียวกันหรืออย่างใดอย่างหนึ่งผ่านองค์ประกอบสุดท้ายของอ็อบเจ็กต์อาร์เรย์ ผลที่ได้คือความแตกต่างของตัวห้อยของทั้งสององค์ประกอบอาร์เรย์ [... ].
ในคำอื่น ๆ ถ้าการแสดงออกP
และQ
ชี้ไปตามลำดับi
-th และj
องค์ประกอบ -th ของวัตถุอาร์เรย์แสดงออก(P)-(Q)
ได้ค่าi−j
ptrdiff_t
บริการที่มีให้พอดีกับค่าในวัตถุของการพิมพ์
ตอนนี้ผมหวังว่าคุณมีความตระหนักของการแปลงชื่ออาร์เรย์ชี้แปรรูปชี้ไปยังองค์ประกอบแรกของอาร์เรย์a
เป็นที่อยู่ของบล็อกหน่วยความจำทั้งหมดคือมันเป็นอยู่ของอาร์เรย์ รูปด้านล่างจะช่วยให้คุณเข้าใจ ( อ่านคำตอบนี้สำหรับคำอธิบายโดยละเอียด ): a
&a
a
นี้จะช่วยให้คุณเข้าใจว่าทำไมa
และ&a
มีที่อยู่เดียวกันและวิธีการที่(&a)[i]
เป็นที่อยู่ของฉันTHอาร์เรย์ (ที่มีขนาดเดียวกันกับที่a
)
ดังนั้นคำสั่ง
return (&a)[n] - a;
เทียบเท่ากับ
return (&a)[n] - (&a)[0];
และความแตกต่างนี้จะให้จำนวนองค์ประกอบระหว่างพอยน์เตอร์(&a)[n]
และ(&a)[0]
ซึ่งคือn
อาร์เรย์แต่ละn
int
องค์ประกอบ ดังนั้นองค์ประกอบมากมายรวมn*n
= 2 n
บันทึก:
C11: 6.5.6 ตัวดำเนินการเพิ่มเติม (p9):
เมื่อทั้งสองตัวชี้จะถูกหัก, ทั้งสองจะชี้ไปที่องค์ประกอบของวัตถุอาร์เรย์เดียวกันหรือหนึ่งในอดีตที่ผ่านมาองค์ประกอบสุดท้ายของวัตถุอาร์เรย์ ; ผลลัพธ์คือความแตกต่างของตัวห้อยขององค์ประกอบอาร์เรย์ทั้งสอง ขนาดของผลลัพธ์ถูกกำหนดโดยการนำไปใช้งานและประเภทของผลลัพธ์ (ชนิดจำนวนเต็มที่ลงนาม) ถูกptrdiff_t
กำหนดไว้ใน<stddef.h>
ส่วนหัว หากไม่สามารถแสดงผลลัพธ์ในออบเจ็กต์ประเภทนั้นได้แสดงว่าพฤติกรรมนั้นไม่ได้กำหนดไว้
ตั้งแต่(&a)[n]
จุดองค์ประกอบของวัตถุอาร์เรย์เดียวกันมิได้หนึ่งที่ผ่านมาองค์ประกอบสุดท้ายของวัตถุอาร์เรย์ไม่และ(&a)[n] - a
จะเรียกไม่ได้กำหนดพฤติกรรม
นอกจากนี้ทราบว่าดีกว่าที่จะเปลี่ยนประเภทการกลับมาของฟังก์ชั่นการ p
ptrdiff_t