คำตอบอื่น ๆ นั้นถูกต้อง แต่ไม่มีคำตอบใดที่เน้นความคิดว่าเป็นไปได้ที่ทั้งสามคนจะมีค่าเท่ากันดังนั้นจึงไม่สมบูรณ์
เหตุผลที่ไม่สามารถเข้าใจได้จากคำตอบอื่น ๆ คือภาพประกอบทั้งหมดในขณะที่มีประโยชน์และสมเหตุสมผลในสถานการณ์ส่วนใหญ่ไม่สามารถครอบคลุมสถานการณ์ที่ตัวชี้ชี้x
ไปที่ตัวเอง
มันค่อนข้างง่ายที่จะสร้าง แต่ชัดเจนยากที่จะเข้าใจ ในโปรแกรมด้านล่างเราจะเห็นว่าเราสามารถบังคับค่าทั้งสามให้เหมือนกันได้อย่างไร
หมายเหตุ:ลักษณะการทำงานในโปรแกรมนี้จะไม่ได้กำหนด แต่ฉันโพสต์ได้ที่นี่อย่างหมดจดเป็นการสาธิตที่น่าสนใจของสิ่งที่ตัวชี้สามารถทำ แต่ไม่ควร
#include <stdio.h>
int main () {
int *(*x)[5];
x = (int *(*)[5]) &x;
printf("%p\n", x[0]);
printf("%p\n", x[0][0]);
printf("%p\n", x[0][0][0]);
}
สิ่งนี้รวบรวมโดยไม่มีคำเตือนทั้งใน C89 และ C99 และผลลัพธ์มีดังต่อไปนี้:
$ ./ptrs
0xbfd9198c
0xbfd9198c
0xbfd9198c
น่าสนใจพอค่าทั้งสามนั้นเหมือนกัน แต่นี่ไม่น่าแปลกใจ! ก่อนอื่นเรามาแบ่งโปรแกรม
เราประกาศx
เป็นตัวชี้ไปยังอาร์เรย์ของ 5 องค์ประกอบที่แต่ละองค์ประกอบเป็นประเภทของตัวชี้ไปยัง int การประกาศนี้จัดสรร 4 ไบต์บนรันไทม์สแต็ก (หรือมากกว่านั้นขึ้นอยู่กับการใช้งานของคุณบนเครื่องพอยน์เตอร์ของฉันคือ 4 ไบต์) ดังนั้นx
อ้างถึงตำแหน่งหน่วยความจำจริง ในตระกูลภาษา C เนื้อหาของx
เป็นเพียงขยะบางสิ่งที่หลงเหลือจากการใช้สถานที่ก่อนหน้านี้ดังนั้นx
ตัวมันเองจึงไม่ได้ชี้ไปที่ใดเลย - แน่นอนว่าจะไม่จัดสรรพื้นที่
ดังนั้นโดยธรรมชาติเราสามารถหาที่อยู่ของตัวแปรx
และวางไว้ที่ไหนสักแห่งนั่นคือสิ่งที่เราทำ แต่เราจะไปข้างหน้าและใส่มันเข้าไปในตัว x เนื่องจาก&x
มีประเภทที่แตกต่างจากx
เราจึงต้องทำการแสดงดังนั้นเราจึงไม่ได้รับคำเตือน
โมเดลหน่วยความจำจะมีลักษณะดังนี้:
0xbfd9198c
+------------+
| 0xbfd9198c |
+------------+
ดังนั้นบล็อก 4 ไบต์ของหน่วยความจำที่อยู่ที่มีรูปแบบบิตที่สอดคล้องกับค่าฐานสิบหก0xbfd9198c
0xbfd9198c
เรียบง่ายพอสมควร
ต่อไปเราจะพิมพ์ค่าสามค่า คำตอบอื่น ๆ จะอธิบายความหมายของแต่ละนิพจน์ดังนั้นความสัมพันธ์ควรจะชัดเจนในขณะนี้
เราสามารถเห็นได้ว่าค่าเหมือนกัน แต่ในระดับต่ำมากเท่านั้น ... รูปแบบบิตของพวกเขาเหมือนกัน แต่ข้อมูลประเภทที่เกี่ยวข้องกับแต่ละนิพจน์หมายความว่าค่าที่ตีความนั้นแตกต่างกัน ตัวอย่างเช่นหากเราพิมพ์x[0][0][0]
โดยใช้สตริงรูปแบบ%d
เราจะได้จำนวนลบมากดังนั้น "ค่า" จึงแตกต่างกัน แต่ในทางปฏิบัติรูปแบบบิตนั้นเหมือนกัน
นี่เป็นเรื่องง่ายจริงๆ ... ในไดอะแกรมลูกศรเพิ่งชี้ไปยังที่อยู่หน่วยความจำเดียวกันมากกว่าที่จะอยู่ต่างหน่วย อย่างไรก็ตามในขณะที่เราสามารถบังคับให้ผลลัพธ์ที่คาดหวังจากพฤติกรรมที่ไม่ได้กำหนดเป็นเพียงแค่นั้น - ไม่ได้กำหนด นี่ไม่ใช่รหัสการผลิต แต่เป็นการสาธิตเพื่อความสมบูรณ์
ในสถานการณ์ที่สมเหตุสมผลคุณจะใช้malloc
เพื่อสร้างอาร์เรย์ของ 5 พอยน์เตอร์พอยน์เตอร์และอีกครั้งเพื่อสร้าง ints ที่ชี้ไปในอาเรย์นั้น malloc
ส่งกลับที่อยู่ที่ไม่ซ้ำกันเสมอ (เว้นแต่ว่าคุณมีหน่วยความจำไม่เพียงพอซึ่งในกรณีนี้จะส่งคืนค่า NULL หรือ 0) ดังนั้นคุณจะไม่ต้องกังวลเกี่ยวกับตัวชี้การอ้างอิงตนเองเช่นนี้
หวังว่านั่นเป็นคำตอบที่คุณต้องการ คุณไม่ควรคาดหวังx[0]
, x[0][0]
และx[0][0][0]
จะเป็นเท่ากัน แต่พวกเขาอาจจะถ้าบังคับ หากมีอะไรเกิดขึ้นในหัวของคุณโปรดแจ้งให้เราทราบเพื่อที่ฉันจะได้อธิบายให้ชัดเจน!
x[0]
,x[0][0]
และx[0][0][0]
มีชนิดที่แตกต่างกัน ไม่สามารถเปรียบเทียบได้ คุณหมายถึง!=
อะไร