Melewati array dengan referensi

184

Bagaimana cara melewatkan array yang dialokasikan secara statis dengan referensi berfungsi?

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

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

Apakah (&myArray)[100]memiliki arti atau hanya sintaksinya untuk melewatkan array apa pun dengan referensi? Saya tidak mengerti tanda kurung terpisah diikuti oleh tanda kurung besar di sini. Terima kasih.

John DB
sumber
Apakah ada hubungan Rvalue ke Lvalue dengan parameter fungsi?
John DB

Jawaban:

228

Ini adalah sintaks untuk referensi array - Anda perlu menggunakan (&array)untuk mengklarifikasi kepada kompiler bahwa Anda ingin referensi ke array, daripada array referensi (tidak valid) int & array[100];.

EDIT: Beberapa klarifikasi.

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

Ketiga cara ini berbeda untuk mendeklarasikan fungsi yang sama. Mereka semua diperlakukan sebagai mengambil int *parameter, Anda bisa mengirimkan ukuran array apa pun kepada mereka.

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

Ini hanya menerima array 100 bilangan bulat. Anda dapat dengan aman menggunakan sizeofpadax

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

Ini diuraikan sebagai "array referensi" - yang tidak sah.

Erik
sumber
Mengapa kita tidak dapat memiliki array referensi misalnya int a, b, c; int arr[3] = {a, b, c};?
Vorac
4
Aha, tau kenapa .
Vorac
2
Bisakah seseorang menjelaskan mengapa void foo(int & x[100]);diuraikan sebagai "array referensi"? Apakah karena aturan "dari-kanan-ke-kiri"? Jika ya, tampaknya tidak konsisten dengan cara void foo(int (&x)[100]);diuraikan sebagai "referensi ke array". Terima kasih sebelumnya.
zl9394
3
Itu tidak benar ke kiri, itu dalam ke luar, dan [] mengikat lebih ketat dari &.
philipxy
48

Hanya sintaks yang diperlukan:

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

^ Lewati array 100 intdengan referensi nama parameternya myArray;

void Func(int* myArray)

^ Pass array. Array meluruh menjadi sebuah pointer. Dengan demikian Anda kehilangan informasi ukuran.

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

^ Lewati penunjuk fungsi. Fungsi mengembalikan suatu intdan mengambil a double. Nama parameternya adalah myFunc.

Martin York
sumber
Bagaimana kita melewatkan array ukuran variabel sebagai referensi?
Shivam Arora
@ShivamArora Anda membuat templat fungsi dan menjadikan ukuran sebagai templat parameter.
Martin York
24

Itu adalah sintaksis. Dalam argumen fungsi int (&myArray)[100]kurung yang melampirkan &myArraydiperlukan. jika Anda tidak menggunakannya, Anda akan melewati array of referencesdan itu karena subscript operator []memiliki prioritas lebih tinggi daripada & operator.

Misalnya int &myArray[100] // array of references

Jadi, dengan menggunakan type construction ()Anda memberi tahu kompiler bahwa Anda ingin referensi ke array 100 integer.

Misalnya int (&myArray)[100] // reference of an array of 100 ints

cpx
sumber
"Jika Anda tidak menggunakannya, Anda akan melewati array of references" - yang tentu saja, tidak ada, sehingga Anda akan mendapatkan kesalahan kompilasi. Ini lucu bagi saya bahwa aturan diutamakan operator bersikeras ini harus terjadi secara default.
underscore_d
Apakah ada tutorial lain tentang konstruksi tipe ()?
Kepala Shifter
Terima kasih, saya membutuhkan penjelasan yang menyertakan alasan tentang diutamakan operator, yang memberikan alasan mengapa itu harus dilakukan dengan cara ini.
cram2208
4

Array adalah standar yang dilewati oleh pointer. Anda dapat mencoba memodifikasi array di dalam pemanggilan fungsi untuk pemahaman yang lebih baik.

Eduardo A. Fernández Díaz
sumber
2
Array tidak dapat diteruskan oleh nilai. Jika fungsi menerima sebuah pointer, sebuah array meluruh ke sebuah pointer ke elemen pertamanya. Saya tidak yakin apa yang ingin Anda katakan di sini.
Ulrich Eckhardt
@UlrichEckhardt Saya mencoba untuk mengatakan bahwa "Array tidak dapat dilewati oleh nilai" seperti yang Anda katakan sebelumnya, mereka secara default disahkan oleh referensi
Eduardo A. Fernández Díaz
8
Array tidak dilewatkan oleh nilai atau referensi. Mereka dilewati oleh pointer. Jika array dilewatkan oleh referensi secara default, Anda tidak akan memiliki masalah menggunakan sizeof pada mereka. Tapi bukan itu masalahnya. Array meluruh ke pointer ketika diteruskan ke suatu fungsi.
user3437460
2
Array dapat dilewatkan dengan referensi ATAU dengan menurunkan ke sebuah pointer. Misalnya, menggunakan char arr[1]; foo(char arr[])., arr menurunkan ke sebuah pointer; saat menggunakan char arr[1]; foo(char (&arr)[1]), arr dilewatkan sebagai referensi. Perlu dicatat bahwa bentuk sebelumnya sering dianggap sebagai bentuk yang buruk karena dimensi hilang.
zl9394
Re, "Array adalah ... dilewati oleh pointer." Deskripsi itu terdengar tidak konvensional, dan mungkin membingungkan bagi pemula. The nama dari variabel array, adalah ekspresi yang valid yang nilainya adalah pointer anggota pertama dari array. Jika Anda memiliki beberapa fungsi foo(T* t), dan Anda memiliki sebuah array T a[N];maka ketika Anda menulis foo(a);saya pikir akan lebih tepat untuk mengatakan bahwa Anda melewati sebuah pointer, tidak melewati sebuah array, dan Anda melewati pointer dengan nilai.
Solomon Slow
1

Berikut ini menciptakan fungsi generik, mengambil array dari berbagai ukuran dan jenis apa pun dengan referensi:

template<typename T, std::size_t S>
void my_func(T (&arr)[S]) {
   // do stuff
}

bermain dengan kodenya.

User12547645
sumber