คุณลักษณะเด่นชัดของภาษาซี (ซึ่งอาจทำให้สับสนด้วย)
คือการปฏิบัติต่อแถวลำดับและตัวชี้ สัญกรณ์แถวลำดับ x[i]
สามารถใช้กับตัวชี้ x ได้ โดยแปลความหมายว่าเป็นการเข้าถึงวัตถุตัวที่ i + 1 ของวัตถุข้อมูลที่อยู่ติดกันถัดจากตำแหน่งที่ x
ชี้อยู่ ซึ่งถือว่าเป็นสมาชิกตัวแรกของแถวลำดับ (x[0])
x[i]
มีความหมายเทียบเท่า *(x + i)
ตามรูปแบบ และเนื่องจากชนิดตัวแปรของตัวชี้เป็นที่ทราบขณะแปล ตำแหน่ง x + i
ที่ชี้ไปมิได้หมายความว่าจากตำแหน่ง x แล้วเพิ่มไปอีก i
ไบต์ แต่หมายถึงเพิ่มไปอีก (i คูณด้วยขนาดของสมาชิกที่ตำแหน่ง x)
ขนาดของสมาชิกนี้ได้มาจากการใช้ตัวดำเนินการ sizeof
บนสมาชิกที่อ้างอิงกลับตัวใดตัวหนึ่งของ x ดังเช่น n = sizeof *x หรือ n =
sizeof x[0]
นอกจากนี้ในบริบทส่วนใหญ่ของนิพจน์
ชื่อของแถวลำดับจะถูกแปลงเป็นตัวชี้ที่ชี้ไปยังสมาชิกตัวแรกของแถวลำดับนั้น
สิ่งนี้บอกเป็นนัยว่าแถวลำดับจะไม่ถูกคัดลอกข้อมูลไปทั้งหมดเมื่อนำไปตั้งชื่ออาร์กิวเมนต์ของฟังก์ชัน
แต่จะมีเพียงแค่ตำแหน่งของสมาชิกตัวแรกเท่านั้นที่ส่งผ่านไป
ดังนั้นถึงแม้ว่าการเรียกใช้ฟังก์ชันในภาษาซีจะตีความว่าส่งโดยให้ค่า
(pass-by-value) แต่แถวลำดับนั้นส่งโดยอ้างอิง
(pass-by-reference) ในทางปฏิบัติ
จำนวนสมาชิกของแถวลำดับ x ที่ได้ประกาศไว้แล้ว
สามารถคำนวณได้จาก sizeof x
/ sizeof x[0]
การสาธิตอย่างหนึ่งที่น่าสนใจต่อความใช้แทนกันได้ระหว่างตัวชี้และแถวลำดับแสดงไว้ด้านล่าง
การกำหนดค่าทั้งสี่มีความหมายเทียบเท่ากันและเป็นรหัสที่ใช้งานได้ในภาษาซี
/* x เป็นแถวลำดับหรือตัวชี้, i เป็นจำนวนเต็ม */
x[i] = 1; /* เทียบเท่ากับ *(x + i) */
*(x + i) =
1;
*(i + x) =
1;
i[x] = 1; /* เทียบเท่ากับ *(i + x) */
แม้ว่าการกำหนดค่าทั้งสี่เทียบเท่ากัน
แต่มีเพียงแบบแรกเท่านั้นที่แสดงรูปแบบการลงรหัสที่ดี กรณีอื่นอาจพบได้ในรหัสภาษาซีที่ยุ่งเหยิง
ถึงอย่างไรก็ตามแถวลำดับและตัวชี้ก็ยังมีจุดที่แตกต่างแม้ว่ามันจะเทียบเท่ากัน
ตัวชี้ไปยังสมาชิกตัวแรกซึ่งแปลงมาจากแถวลำดับ
ไม่มีเนื้อที่เก็บข้อมูลตำแหน่งของมันเอง ต่างจากตัวแปรตัวชี้ซึ่งมี
เมื่อเป็นเช่นนั้นแล้วสิ่งที่แถวลำดับ "ชี้ไป" จึงไม่สามารถเปลี่ยนแปลงได้
และไม่สามารถกำหนดค่าใหม่ให้กับตัวแปรแถวลำดับ (ค่าต่าง ๆ ของแถวลำดับอาจคัดลอกได้
โดยใช้ฟังก์ชัน memcpy เป็นต้น)
ไม่มีความคิดเห็น:
แสดงความคิดเห็น