เข้าใจ sizeof
ใน C++: ทำไม n
จึงไม่เท่ากับ 8
?
เมื่อทำงานกับอาร์เรย์ใน C++ คุณอาจพบผลลัพธ์ที่คาดไม่ถึงเกี่ยวกับตัวดำเนินการ sizeof
โดยเฉพาะอย่างยิ่งเมื่อส่งอาร์เรย์ไปยังฟังก์ชัน ในบล็อกโพสต์นี้เราจะสำรวจความสับสนทั่วไปที่เกิดขึ้นเมื่อใช้ sizeof
กับพารามิเตอร์ของฟังก์ชัน โดยเฉพาะการตอบคำถาม: ทำไม n
จึงไม่เท่ากับ 8
ในฟังก์ชัน foo()
?
ปัญหา
มาลองพิจารณาสองตัวอย่างโค้ดที่แสดงปัญหานี้:
ตัวอย่างที่ 1: ฟังก์ชัน foo()
void foo(char cvalue[8])
{
int n = sizeof(cvalue);
}
ในตัวอย่างข้างต้น เมื่อต้องการเรียก sizeof(cvalue)
คุณอาจคาดหวังว่า n
จะเท่ากับ 8
เนื่องจากอาร์เรย์ถูกกำหนดขนาดไว้ที่ 8
แต่สถานการณ์นั้นไม่เป็นเช่นนั้น
ตัวอย่างที่ 2: ฟังก์ชัน bar()
void bar()
{
char cvalue[8];
int n = sizeof(cvalue);
}
ในตัวอย่างที่สอง sizeof(cvalue)
จะมีค่าเท่ากับ 8
ดังนั้นทำไมถึงมีความแตกต่าง?
เข้าใจแนวคิด
เพื่อที่จะเข้าใจว่า sizeof(cvalue)
คืนค่าแตกต่างกันในแต่ละฟังก์ชันได้อย่างไร เราต้องชี้แจงว่าอาร์เรย์ถูกปฏิบัติอย่างไรใน C และ C++
อาร์เรย์เป็นพารามิเตอร์ฟังก์ชัน
เมื่อคุณส่งอาร์เรย์ไปยังฟังก์ชันใน C หรือ C++ คุณไม่ได้ส่งอาร์เรย์จริง ๆ แต่ในความเป็นจริงคุณกำลังส่งพอยเตอร์ไปยังสมาชิกแรกของอาร์เรย์ สัญลักษณ์วงเล็บที่ใช้ในพารามิเตอร์ฟังก์ชันนั้นเพียงแค่เป็นการสังเคราะห์ซึ่งไม่ได้เปลี่ยนแปลงพฤติกรรม—การประกาศทั้งสองนี้เป็นสิ่งที่เทียบเท่ากัน:
void foo(char cvalue[8])
void foo(char cvalue[])
void foo(char *cvalue)
ในการประกาศเหล่านี้ทั้งหมด cvalue
จะถูกตีความว่าเป็นพอยเตอร์ ดังนั้นเมื่อคุณเรียก sizeof(cvalue)
ภายใน foo()
มันจะคืนขนาดของพอยเตอร์ไม่ใช่ขนาดของอาร์เรย์ บนแพลตฟอร์มส่วนใหญ่ขนาดนี้มักจะเป็น 4
ไบต์ในระบบ 32 บิตและ 8
ไบต์ในระบบ 64 บิต ซึ่งเป็นเหตุผลที่ n
ไม่เท่ากับ 8
ใน foo()
บริบทที่ถูกต้องใน bar()
ในทางกลับกัน ภายใน bar()
cvalue
ถูกกำหนดให้เป็นอาร์เรย์ท้องถิ่นขนาด 8
ดังนั้นเมื่อเรียกใช้ sizeof(cvalue)
ที่นี่มันจะสะท้อนขนาดของอาร์เรย์ทั้งหมดอย่างถูกต้อง ทำให้ n
เท่ากับ 8
ข้อคิดสำคัญ
- เข้าใจพฤติกรรมของพอยเตอร์: เมื่อส่งอาร์เรย์เป็นพารามิเตอร์ คุณมักจะส่งพอยเตอร์ ซึ่งอาจนำไปสู่ค่าที่สับสนเมื่อใช้
sizeof
- อาร์เรย์ท้องถิ่น:
sizeof
แสดงขนาดจริงของอาร์เรย์ท้องถิ่นที่กำหนดไว้ภายในฟังก์ชัน ทำให้ได้ผลลัพธ์ที่คาดหวัง - การเขียนที่เป็นโครงสร้าง: สัญลักษณ์วงเล็บในพารามิเตอร์ฟังก์ชันไม่ได้สร้างตัวแปรอาร์เรย์ แต่บ่งชี้ว่าคุณกำลังจัดการพอยเตอร์
สรุป
การจัดการอาร์เรย์ใน C และ C++ อาจเป็นเรื่องท้าทาย โดยเฉพาะสำหรับผู้ที่ใหม่ต่อภาษา ความเข้าใจความแตกต่างระหว่างพอยเตอร์และอาร์เรย์จึงมีความสำคัญต่อการคำนวณและการดีบักอย่างถูกต้อง จำไว้ว่าขณะที่คุณอยู่ภายในฟังก์ชัน sizeof
ที่ใช้กับพารามิเตอร์ที่ถือว่าเป็นอาร์เรย์จะให้ขนาดของพอยเตอร์ ไม่ใช่ขนาดของอาร์เรย์ที่คุณตั้งใจจะส่ง
หวังว่าคำอธิบายนี้จะช่วยให้เข้าใจพฤติกรรมของตัวดำเนินการ sizeof
เกี่ยวกับอาร์กิวเมนต์อาร์เรย์ในฟังก์ชัน และชี้แจงเหตุผลที่ทำให้ n
ไม่เท่ากับ 8
ในฟังก์ชัน foo()
แต่เท่าใน bar()
จงจำหลักการเหล่านี้ขณะเขียนโค้ด!