Проходження масиву за посиланням


184

Як працює передача статично розподіленого масиву за посиланням?

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

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

Чи (&myArray)[100]має якесь значення або його просто синтаксис для передачі будь-якого масиву за посиланням? Я не розумію окремих дужок, за якими тут стоять великі дужки. Дякую.


Чи є відношення Rvalue до Lvalue з параметрами функції?
Джон БД


Відповіді:


228

Це синтаксис посилань на масив - вам потрібно використовувати, (&array)щоб уточнити компілятору, що ви хочете посилання на масив, а не (недійсний) масив посилань int & array[100];.

EDIT: Деякі роз’яснення.

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

Це аналізується як "масив посилань" - що не є законним.


Чому ми не можемо мати масив посилань, наприклад int a, b, c; int arr[3] = {a, b, c};?
Ворак

4
Ага, з’ясував, чому .
Vorac

2
Може хтось пояснить, чому, void foo(int & x[100]);будь ласка, розбирається як "масив посилань"? Це тому, що правило "справа наліво"? Якщо так, то, схоже, це не відповідає тому, як void foo(int (&x)[100]);аналізується як "посилання на масив". Заздалегідь спасибі.
zl9394

3
Не праворуч ліворуч, воно зсередини, і [] прив’язується міцніше, ніж &.
філіпсі

48

Це просто необхідний синтаксис:

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

^ Передати масив 100 intза посиланням на ім'я параметрів myArray;

void Func(int* myArray)

^ Передати масив. Масив розпадається на покажчик. Таким чином ви втрачаєте інформацію про розмір.

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

^ Передати покажчик функції. Функція повертає a intі приймає a double. Ім'я параметра myFunc.


Як ми можемо передати масив змінних розмірів як орієнтир?
Шивам Арора

@ShivamArora Ви шаблонуєте функцію та робите розмір параметром шаблону.
Мартін Йорк

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" - що, звичайно, не може існувати, тож ви отримаєте помилку компіляції. Мені цікаво, що правила пріоритетності оператора стверджують, що це все одно має відбутися за замовчуванням.
підкреслюй_

Чи є ще підручник щодо типу конструкції ()?
Головний перемикач

Дякую, мені було потрібне пояснення, яке включало причину пріоритету оператора, що дає сенс, чому це слід робити так.
cram2208

4

Масиви за замовчуванням передаються вказівниками. Ви можете спробувати змінити масив всередині виклику функції для кращого розуміння.


2
Масиви не можна передавати за значенням. Якщо функція отримує вказівник, масив відхиляється від вказівника на його перший елемент. Я не впевнений, що ви намагаєтесь сказати тут.
Ульріх Екхардт

@UlrichEckhardt Я намагаюся сказати, що "Масиви не можуть бути передані за значенням", як ви сказали раніше, вони за замовчуванням передаються посиланням
Eduardo A. Fernández Díaz

8
Масив не передається ні за значенням, ні за посиланням. Їх передають покажчики. Якщо масиви передаються посиланням за замовчуванням, у вас не буде проблем із застосуванням sizeof. Але це не так. Масиви розпадаються на покажчики при переході у функцію.
користувач3437460

2
Масиви можуть бути передані посиланням АБО шляхом пониження до покажчика. Наприклад, використовуючи char arr[1]; foo(char arr[])., arr погіршує показник; під час використання char arr[1]; foo(char (&arr)[1])arr передається як еталон. Примітно, що колишня форма часто вважається погано сформованою, оскільки втрачається вимір.
zl9394

Re: "Масиви ... проходять вказівниками". Цей опис у кращому випадку звучить нетрадиційно, і для новачків це може бентежити. Ім'я з змінного масиву, є допустимим виразом, значення якого є Піковим першим елементом масиву. Якщо у вас є якась функція foo(T* t), і у вас є масив, T a[N];тоді, коли ви пишете, foo(a);я вважаю, що було б правильніше сказати, що ви передаєте вказівник, а не передаєте масив, і ви передаєте вказівник за значенням.
Соломон повільно

1

Далі створюється загальна функція, приймаючи масив будь-якого розміру та будь-якого типу за посиланням:

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

грати з кодом.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.