แบบอิงตามช่วงสำหรับการทำงานสำหรับอาร์เรย์ธรรมดาอย่างไร
ที่จะอ่านว่า " บอกฉันทีว่า ranged-for ทำ (พร้อมอาร์เรย์) คืออะไร? "
ฉันจะตอบโดยสมมติว่า - ใช้ตัวอย่างต่อไปนี้โดยใช้อาร์เรย์ที่ซ้อนกัน:
int ia[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
for (auto &pl : ia)
เวอร์ชันข้อความ:
ia
คืออาร์เรย์ของอาร์เรย์ ("อาร์เรย์ที่ซ้อนกัน") ซึ่งมี[3]
อาร์เรย์โดยแต่ละอาร์เรย์มี[4]
ค่า ตัวอย่างข้างต้นวนia
ซ้ำโดยเป็น 'range' ( [3]
) หลักดังนั้นจึงวน[3]
ซ้ำ แต่ละวงผลิตหนึ่งia
ของ[3]
ค่าหลักเริ่มจากคนแรกและลงท้ายด้วยที่ผ่านมา - อาร์เรย์ที่มี[4]
ค่า
- ลูปแรก:
pl
เท่ากับ{1,2,3,4}
- อาร์เรย์
- วงที่สอง:
pl
เท่ากับ{5,6,7,8}
- อาร์เรย์
- วงที่สาม:
pl
เท่ากับ{9,10,11,12}
- อาร์เรย์
ก่อนที่เราจะอธิบายกระบวนการต่อไปนี้เป็นคำเตือนที่เป็นมิตรเกี่ยวกับอาร์เรย์:
- อาร์เรย์ถูกตีความว่าเป็นพอยน์เตอร์สำหรับค่าแรก - การใช้อาร์เรย์โดยไม่มีการวนซ้ำจะส่งกลับแอดเดรสของค่าแรก
pl
ต้องเป็นข้อมูลอ้างอิงเนื่องจากเราไม่สามารถคัดลอกอาร์เรย์ได้
- ด้วยอาร์เรย์เมื่อคุณเพิ่มตัวเลขลงในอ็อบเจ็กต์อาร์เรย์เองมันจะเลื่อนไปข้างหน้าหลาย ๆ ครั้งและ 'ชี้' ไปยังรายการที่เทียบเท่า - หาก
n
เป็นตัวเลขที่เป็นปัญหาก็ia[n]
จะเหมือนกับ*(ia+n)
(เรากำลังยกเลิกการอ้างอิงที่อยู่ที่เป็นn
รายการ ไปข้างหน้า) และia+n
เหมือนกับ&ia[n]
(เราได้รับที่อยู่ของรายการนั้นในอาร์เรย์)
นี่คือสิ่งที่เกิดขึ้น:
- ในแต่ละวง
pl
จะถูกตั้งค่าเป็นอ้างอิงจะia[n]
มีn
เท่ากับจำนวนวงในปัจจุบันที่เริ่มต้นจาก 0. ดังนั้นpl
คือia[0]
ในรอบแรกที่สองมันเป็นia[1]
และอื่น ๆ มันดึงค่าผ่านการวนซ้ำ
- ห่วงไปในตราบใดที่มีค่าน้อยกว่า
ia+n
end(ia)
... และนั่นก็คือเรื่องนี้
มันเป็นเพียงวิธีง่ายๆในการเขียนสิ่งนี้ :
int ia[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
for (int n = 0; n != 3; ++n)
auto &pl = ia[n];
หากอาร์เรย์ของคุณไม่ได้ซ้อนกันกระบวนการนี้จะง่ายกว่าเล็กน้อยเนื่องจากไม่จำเป็นต้องใช้การอ้างอิงเนื่องจากค่าที่ทำซ้ำไม่ใช่อาร์เรย์ แต่เป็นค่า 'ปกติ':
int ib[3] = {1,2,3};
for (auto pl : ib)
cout << pl;
for (int n = 0; n != 3; ++n)
cout << ib[n];
ข้อมูลเพิ่มเติมบางอย่าง
จะเกิดอะไรขึ้นถ้าเราไม่ต้องการใช้auto
คีย์เวิร์ดในการสร้างpl
? หน้าตาจะเป็นอย่างไร?
ในตัวอย่างต่อไปนี้pl
อ้างถึงไฟล์array of four integers
ไฟล์. ในแต่ละวงpl
จะได้รับค่าia[n]
:
int ia[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
for (int (&pl)[4] : ia)
นั่นคือวิธีการทำงานพร้อมข้อมูลเพิ่มเติมเพื่อขจัดความสับสน มันเป็นเพียงการfor
วนซ้ำ'ชวเลข' ที่นับให้คุณโดยอัตโนมัติ แต่ไม่มีวิธีดึงลูปปัจจุบันโดยไม่ต้องทำเอง
for
ขนาดของมันมีการเข้ารหัสในประเภทและสามารถเข้าถึงได้โดย แต่ในขณะที่อาร์เรย์สลายตัวไปยังตัวชี้ข้อมูลขนาดจะหายไป