แบบอิงตามช่วงสำหรับการทำงานสำหรับอาร์เรย์ธรรมดาอย่างไร
ที่จะอ่านว่า " บอกฉันทีว่า 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+nend(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ขนาดของมันมีการเข้ารหัสในประเภทและสามารถเข้าถึงได้โดย แต่ในขณะที่อาร์เรย์สลายตัวไปยังตัวชี้ข้อมูลขนาดจะหายไป