"Decay" หมายถึงการแปลงโดยนัยของนิพจน์จากประเภทอาเรย์เป็นประเภทพอยน์เตอร์ ในบริบทส่วนใหญ่เมื่อคอมไพเลอร์เห็นการแสดงออกของอาร์เรย์มันจะแปลงประเภทของการแสดงออกจาก "อาร์เรย์องค์ประกอบ N ของ T" เป็น "ตัวชี้ไปที่ T" และตั้งค่าของการแสดงออกไปยังที่อยู่ขององค์ประกอบแรกของอาร์เรย์ . ข้อยกเว้นของกฎนี้คือเมื่ออาร์เรย์เป็นตัวถูกดำเนินการของsizeof
หรือ&
ตัวดำเนินการหรืออาร์เรย์เป็นตัวอักษรสตริงที่ใช้เป็นตัวเริ่มต้นในการประกาศ
สมมติว่ารหัสต่อไปนี้:
char a[80];
strcpy(a, "This is a test");
การแสดงออกa
เป็นประเภท "อาร์เรย์ 80 องค์ประกอบของถ่าน" และการแสดงออก "นี่คือการทดสอบ" เป็นประเภท "อาร์เรย์ 16 องค์ประกอบของถ่าน" (ใน C; ในตัวอักษร C สตริงสตริง C ++ เป็นอาร์เรย์ของ const ถ่าน) อย่างไรก็ตามในการเรียกไปยังstrcpy()
นิพจน์ไม่ได้เป็นตัวถูกดำเนินการของsizeof
หรือ&
ดังนั้นประเภทของพวกเขาจะถูกแปลงโดยปริยายเป็น "ตัวชี้ไปยังถ่าน" และค่าของพวกเขาจะถูกตั้งค่าเป็นที่อยู่ขององค์ประกอบแรกในแต่ละ สิ่งที่strcpy()
ได้รับไม่ใช่อาร์เรย์ แต่เป็นพอยน์เตอร์ดังที่เห็นในต้นแบบ:
char *strcpy(char *dest, const char *src);
สิ่งนี้ไม่เหมือนกับตัวชี้อาร์เรย์ ตัวอย่างเช่น:
char a[80];
char *ptr_to_first_element = a;
char (*ptr_to_array)[80] = &a;
ทั้งสองptr_to_first_element
และptr_to_array
มีเดียวกันค่า ; ที่อยู่ฐานของ อย่างไรก็ตามมีหลายประเภทและได้รับการปฏิบัติต่างกันดังที่แสดงด้านล่าง:
a[i] == ptr_to_first_element[i] == (*ptr_to_array)[i] != *ptr_to_array[i] != ptr_to_array[i]
โปรดจำไว้ว่านิพจน์a[i]
นั้นถูกตีความว่าเป็น*(a+i)
(ซึ่งใช้ได้เฉพาะถ้าประเภทอาเรย์ถูกแปลงเป็นประเภทพอยน์เตอร์) ดังนั้นทั้งสองa[i]
และptr_to_first_element[i]
ทำงานเหมือนกัน การแสดงออกถูกตีความว่าเป็น(*ptr_to_array)[i]
*(*a+i)
การแสดงออก*ptr_to_array[i]
และptr_to_array[i]
อาจนำไปสู่คำเตือนหรือข้อผิดพลาดคอมไพเลอร์ขึ้นอยู่กับบริบท; a[i]
แน่นอนพวกเขาจะทำในสิ่งที่ผิดถ้าคุณคาดหวังว่าพวกเขาจะประเมิน
sizeof a == sizeof *ptr_to_array == 80
อีกครั้งเมื่ออาร์เรย์เป็นตัวถูกดำเนินการsizeof
จะไม่ถูกแปลงเป็นประเภทตัวชี้
sizeof *ptr_to_first_element == sizeof (char) == 1
sizeof ptr_to_first_element == sizeof (char *) == whatever the pointer size
is on your platform
ptr_to_first_element
เป็นตัวชี้ง่าย ๆ ที่จะถ่าน
int a[10]; int b(void);
จากนั้น+a
เป็นตัวชี้ int และ+b
เป็นตัวชี้ฟังก์ชั่น มีประโยชน์หากคุณต้องการส่งต่อให้แม่แบบที่ยอมรับการอ้างอิง