ผ่านอาร์เรย์โดยอ้างอิง


184

การส่งผ่านอาร์เรย์ที่จัดสรรแบบคงที่โดยการอ้างอิงทำงานอย่างไร

void foo(int (&myArray)[100])
{
}

int main()
{
    int a[100];
    foo(a);
}

ไม่(&myArray)[100]ได้มีความหมายใด ๆ หรือเพียงแค่ไวยากรณ์ของมันจะผ่านอาร์เรย์ใด ๆ โดยการอ้างอิง? ฉันไม่เข้าใจวงเล็บแยกตามด้วยวงเล็บใหญ่ที่นี่ ขอบคุณ


มีความสัมพันธ์ Rvalue ถึง Lvalue กับพารามิเตอร์ฟังก์ชันหรือไม่
John DB


การทำซ้ำที่เป็น
Anatolyg

คำตอบ:


228

มันเป็นไวยากรณ์สำหรับการอ้างอิงอาร์เรย์ - คุณจำเป็นต้องใช้(&array)ในการชี้แจงการคอมไพเลอร์ที่คุณต้องการการอ้างอิงไปยังอาร์เรย์มากกว่า (ไม่ถูกต้อง) int & array[100];อาร์เรย์ของการอ้างอิง

แก้ไข: ชี้แจงบางส่วน

void foo(int * x);
void foo(int x[100]);
void foo(int x[]);

ทั้งสามนี้เป็นวิธีการที่แตกต่างกันในการประกาศฟังก์ชั่นเดียวกัน พวกเขาทั้งหมดถือว่าเป็นint *พารามิเตอร์คุณสามารถผ่านอาร์เรย์ขนาดใด ๆ ให้พวกเขา

void foo(int (&x)[100]);

สิ่งนี้ยอมรับเฉพาะอาร์เรย์ของจำนวนเต็ม 100 ตัว คุณสามารถใช้sizeofบนx

void foo(int & x[100]); // error

นี่คือการแยกวิเคราะห์เป็น "อาร์เรย์ของการอ้างอิง" - ซึ่งไม่ถูกกฎหมาย


ทำไมเราไม่สามารถมีอาร์เรย์ของการอ้างอิง e กรัมint a, b, c; int arr[3] = {a, b, c};?
Vorac

4
อ้าพบว่าทำไม
Vorac

2
มีคนอธิบายได้void foo(int & x[100]);ไหมว่าเพราะเหตุใดจึงมีการแยกวิเคราะห์เป็น "อาร์เรย์ของข้อมูลอ้างอิง" โปรด เป็นเพราะกฎ "จากขวาไปซ้าย" ใช่ไหม ถ้าใช่ดูเหมือนว่าจะไม่สอดคล้องกับวิธีการvoid foo(int (&x)[100]);แยกวิเคราะห์เป็น "อ้างอิงถึงอาร์เรย์" ขอบคุณล่วงหน้า.
zl9394

3
มันไม่ถูกต้องที่จะออกไปข้างนอกข้างในและ [] ผูกให้แน่นกว่า &
philipxy

48

มันเป็นเพียงไวยากรณ์ที่จำเป็น:

void Func(int (&myArray)[100])

^ ผ่านอาร์เรย์ 100 intโดยอ้างอิงชื่อพารามิเตอร์คือmyArray;

void Func(int* myArray)

^ ส่งผ่านอาร์เรย์ Array จะสลายตัวไปยังตัวชี้ ดังนั้นคุณสูญเสียข้อมูลขนาด

void Func(int (*myFunc)(double))

^ ผ่านตัวชี้ฟังก์ชั่น ฟังก์ชั่นส่งกลับและใช้เวลาint ชื่อพารามิเตอร์doublemyFunc


เราจะส่งผ่านอาร์เรย์ขนาดตัวแปรเป็นข้อมูลอ้างอิงได้อย่างไร
Shivam Arora

@ShivamArora คุณสร้างฟังก์ชันและทำให้ขนาดเป็นพารามิเตอร์เทมเพลต
Martin York

24

มันเป็นไวยากรณ์ ในint (&myArray)[100]วงเล็บฟังก์ชั่นข้อโต้แย้งที่ล้อมรอบ&myArrayมีความจำเป็น ถ้าคุณไม่ใช้พวกเขาคุณจะส่งผ่านarray of referencesและนั่นเป็นเพราะมีความสำคัญสูงกว่าsubscript operator []& operator

เช่น int &myArray[100] // array of references

ดังนั้นโดยใช้type construction ()คุณบอกคอมไพเลอร์ว่าคุณต้องการการอ้างอิงถึงอาร์เรย์จำนวนเต็ม 100 ตัว

เช่น int (&myArray)[100] // reference of an array of 100 ints


"ถ้าคุณไม่ได้ใช้คุณจะต้องผ่านarray of references" - ซึ่งไม่มีอยู่จริงดังนั้นคุณจึงได้รับข้อผิดพลาดในการคอมไพล์ สำหรับฉันแล้วมันก็น่าขบขันที่กฎการดำเนินการมาก่อนยืนยันว่าจะต้องเกิดขึ้นตามค่าเริ่มต้นอยู่ดี
underscore_d

มีบทช่วยสอนเกี่ยวกับการสร้างประเภท () อีกหรือไม่
Chief Shifter

ขอบคุณฉันต้องการคำอธิบายที่รวมถึงเหตุผลเกี่ยวกับความสำคัญของผู้ปฏิบัติงานซึ่งให้เหตุผลว่าทำไมจึงควรทำเช่นนี้
cram2208

4

อาร์เรย์เป็นค่าเริ่มต้นที่ส่งผ่านโดยพอยน์เตอร์ คุณสามารถลองปรับเปลี่ยนอาร์เรย์ภายในการเรียกใช้ฟังก์ชันเพื่อความเข้าใจที่ดีขึ้น


2
ไม่สามารถส่งค่าอาร์เรย์ได้ ถ้าฟังก์ชั่นได้รับพอยน์เตอร์อาร์เรย์จะสลายไปเป็นพอยน์เตอร์ไปยังองค์ประกอบแรก ฉันไม่แน่ใจว่าคุณกำลังพยายามพูดอะไรที่นี่
Ulrich Eckhardt

@UlrichEckhardt ฉันพยายามที่จะพูดว่า "อาร์เรย์ไม่สามารถผ่านค่า" ตามที่คุณพูดก่อนหน้านี้พวกเขาจะเริ่มต้นผ่านการอ้างอิง
Eduardo A. FernándezDíaz

8
อาร์เรย์ไม่ถูกส่งผ่านโดยค่าหรือการอ้างอิง พวกเขาถูกส่งผ่านโดยตัวชี้ หากอาร์เรย์ถูกส่งผ่านโดยการอ้างอิงโดยค่าเริ่มต้นคุณจะไม่มีปัญหาในการใช้ขนาดของพวกเขา แต่นั่นไม่ใช่กรณี อาร์เรย์สลายตัวไปยังพอยน์เตอร์เมื่อส่งผ่านไปยังฟังก์ชัน
user3437460

2
อาร์เรย์สามารถส่งผ่านโดยการอ้างอิงหรือโดยการลดระดับลงไปที่ตัวชี้ ตัวอย่างเช่นการใช้char arr[1]; foo(char arr[]).arr ลดระดับลงไปที่ตัวชี้ ในขณะที่ใช้char arr[1]; foo(char (&arr)[1])งาน arr จะถูกส่งผ่านเป็นข้อมูลอ้างอิง เป็นที่น่าสังเกตว่ารูปแบบในอดีตมักถูกมองว่าเป็นรูปแบบที่ไม่ดีเนื่องจากมิติหายไป
zl9394

ตอบ "อาร์เรย์คือ ... ผ่านตัวชี้" คำอธิบายนั้นฟังดูแปลกและดีสำหรับมือใหม่ ชื่อของตัวแปรอาร์เรย์คือการแสดงออกที่ถูกต้องมีค่าเป็นตัวชี้เป็นสมาชิกคนแรกของอาร์เรย์ หากคุณมีฟังก์ชั่นบางอย่างfoo(T* t)และคุณมีอาเรย์T a[N];แล้วเมื่อคุณเขียนfoo(a);ฉันคิดว่ามันจะถูกต้องมากขึ้นที่จะบอกว่าคุณกำลังส่งพอยน์เตอร์ไม่ผ่านอาเรย์และคุณกำลังส่งพอยน์เตอร์ตามค่า
โซโลมอนช้า

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.