เพื่อทำความเข้าใจแฮ็กนี้ ก่อนอื่นคุณต้องเข้าใจความแตกต่างของพอยน์เตอร์ กล่าวคือ จะเกิดอะไรขึ้นเมื่อพอยน์เตอร์สองตัวที่ชี้ไปยังองค์ประกอบของ อาร์เรย์เดียวกัน ถูกลบออก
เมื่อลบพอยน์เตอร์ตัวหนึ่งออกจากอีกพอยน์เตอร์ ผลลัพธ์ที่ได้คือระยะห่าง (วัดในองค์ประกอบอาร์เรย์) ระหว่างพอยน์เตอร์เหล่านั้น ดังนั้น หาก 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
strong> โดยให้ค่าพอดีกับวัตถุประเภท ptrdiff_t
ตอนนี้ฉันคาดหวังว่าคุณจะทราบถึงการแปลงชื่ออาร์เรย์เป็นตัวชี้ a
แปลงเป็นตัวชี้เป็นองค์ประกอบแรกของอาร์เรย์ a
&a
คือที่อยู่ของบล็อกหน่วยความจำทั้งหมด กล่าวคือ เป็นที่อยู่ของอาร์เรย์ a
รูปด้านล่างจะช่วยให้คุณเข้าใจ (อ่าน คำตอบนี้ สำหรับคำอธิบายโดยละเอียด):
นี่จะช่วยให้คุณเข้าใจว่าเหตุใด a
และ &a
จึงมีที่อยู่เดียวกัน และ (&a)[i]
เป็นที่อยู่ของอาร์เรย์ที่ ith อย่างไร (ที่มีขนาดเท่ากับของ a
)
ดังนั้นแถลงการณ์
return (&a)[n] - a;
เทียบเท่ากับ
return (&a)[n] - (&a)[0];
และความแตกต่างนี้จะให้จำนวนองค์ประกอบระหว่างพอยน์เตอร์ (&a)[n]
และ (&a)[0]
ซึ่งเป็นอาร์เรย์ n
แต่ละองค์ประกอบจาก n
int
องค์ประกอบ ดังนั้น องค์ประกอบอาร์เรย์ทั้งหมดคือ n*n
= n
2
หมายเหตุ:
C11: 6.5.6 ตัวดำเนินการบวก (p9):
เมื่อลบพอยน์เตอร์สองตัว ทั้งสองจะต้องชี้ไปที่องค์ประกอบของออบเจ็กต์อาร์เรย์เดียวกัน หรือหนึ่งตัวเลยองค์ประกอบสุดท้ายของออบเจ็กต์อาร์เรย์; ผลลัพธ์คือความแตกต่างของตัวห้อยขององค์ประกอบอาร์เรย์ทั้งสอง ขนาดของผลลัพธ์เป็นแบบกำหนดการใช้งาน และประเภทของผลลัพธ์ (ประเภทจำนวนเต็มที่ลงนาม) คือ ptrdiff_t
ที่กำหนดไว้ในส่วนหัว <stddef.h>
หากผลลัพธ์ไม่สามารถแสดงในออบเจ็กต์ประเภทนั้นได้ แสดงว่าพฤติกรรมนั้นไม่ได้ถูกกำหนดไว้
เนื่องจาก (&a)[n]
ไม่ได้ชี้ไปที่องค์ประกอบของออบเจ็กต์อาร์เรย์เดียวกันหรือไม่ได้ชี้ไปที่องค์ประกอบสุดท้ายของออบเจ็กต์อาร์เรย์ (&a)[n] - a
จะเรียกใช้ พฤติกรรมที่ไม่ได้กำหนด
โปรดทราบว่าควรเปลี่ยนประเภทการส่งคืนของฟังก์ชัน p
เป็น ptrdiff_t
จะดีกว่า
person
haccks
schedule
07.01.2015
int p(n)
? นั่นมันคอมไพล์ด้วยเหรอ? - person barak manos   schedule 08.01.2015gcc
- person lurker   schedule 08.01.2015int q(int n) { return sizeof (char [n][n]); }
- person ouah   schedule 08.01.2015sizeof
คือการบันทึกอักขระ คนอื่นๆ: นี่เป็นโค้ดที่คลุมเครือโดยเจตนา มันเป็นพฤติกรรมที่ไม่ได้กำหนดไว้ คำตอบของ @ouah นั้นถูกต้อง - person ecatmur   schedule 08.01.2015O(n^2)
เพื่อคำนวณn^2
- person Khaled.K   schedule 14.01.2015