Путаница массив / указатель / ссылка

Возможный дубликат:
Путаница в C ++

Предположим, я прохожу

int arr[10];

в качестве параметра для функции.

Являются ли все эти действительные прототипы функций? Чем они отличаются с точки зрения аргументов и почему?

Это то, что я знаю до сих пор (не уверен, правильно ли это или нет)

1. void foo(int &arr);      //a reference to an array, which preserve the size attribute?
2. void foo(int &arr[]);    //the same (is it)?
3. void foo(int (&arr)[]);  //I don't know
4. void foo(int &arr[10]);  //is it the same as 2?
5. void foo(int (&arr)[10]);//no idea

6. void foo(int *arr);      //a decayed pointer of the array, pointing to the first element of the array, losing the size attribute?

7. void foo(int *arr[]);    //the same (is it?)
8. void foo(int (*arr)[]);  //a pointer to an array, preserve the size
9. void foo(int *arr[10]);  //the same as 7 (is it?)
10. void foo(int (*arr)[10]);//is the same as 8 (is it?)

11. void foo(int arr[]);    //is the same as 6 (is it?)
12. void foo(int arr[10]);  // is the same as 6 (is it?)

(Я знаю, что это потребует длинного объяснения, извините, я полностью запутался …)

3

Решение

Первая важная часть информации — это параметры, тип которых (ограниченный или неограниченный) массив T преобразуются в указатели на T, То есть и то и другое int arr[] а также int arr[10] превращаются в int * arr, Обратите внимание, что преобразование выполняется только для массивов верхнего уровня, т. Е. Оно не выполняется в int (*arr)[10], который является указателем на массив int.

Кроме того, вещи справа от идентификатора связываются более тесно, чем вещи слева, т.е. int *arr[10] это массив, тогда как int (*arr)[10] это указатель

Наконец, массивы и указатели на ссылки недействительны, так же как указатели и ссылки на неограниченные массивы.

1. void foo(int &arr);        // can't pass, reference to int
2. void foo(int &arr[]);      // invalid, pointer to reference to int
3. void foo(int (&arr)[]);    // invalid, reference to unbounded array of int
4. void foo(int &arr[10]);    // invalid, pointer to reference to int
5. void foo(int (&arr)[10]);  // can pass, reference to an array of int

6. void foo(int *arr);        // can pass, pointer to int
7. void foo(int *arr[]);      // can't pass, pointer to pointer to int
8. void foo(int (*arr)[]);    // invalid, pointer to an unbounded array of int.
9. void foo(int *arr[10]);    // can't pass, pointer to pointer to int
10. void foo(int (*arr)[10]); // can't pass, pointer to array of int

11. void foo(int arr[]);      // can pass, pointer to int
12. void foo(int arr[10]);    // can pass, same as above

С помощью arr в качестве аргумента foo заставит его затухать до указателя на его первый элемент — значение передается foo будет иметь тип int *, Обратите внимание, что вы можете пройти &arr на номер 10, в этом случае значение типа int (*)[10] будет пройден, и не будет никакого распада.

8

Другие решения

Сложность состоит в том, чтобы считать, что массив не передается по значению, а распадается на указатели.

Некоторые из ваших деклараций являются синтаксическими ошибками, другие — нет (но также не являются тем, о чем вы, вероятно, думаете)

В вашем случае только один имеет смысл: 6, 11 и 12.

2, 3, 4 и 8 имеют понятные сообщения об ошибках. (если вы не понимаете их, скорее всего, потому что вы прочитали объявление с неправильным приоритетом оператора)

t1.cpp:2:19: error: declaration of 'arr' as array of references
t1.cpp:3:22: error: parameter 'arr' includes reference to array of unknown bound 'int []'
t1.cpp:4:21: error: declaration of 'arr' as array of references
t1.cpp:8:22: error: parameter 'arr' includes pointer to array of unknown bound 'int []'

Другие являются как-то избыточными (ссылка на массив или -pointer-, они будут вести себя одинаково внутри функции) или просто неправильны, потому что объявляют что-то другое, как вы намерены (например, 7,9,10: они представляют «двойное косвенное обращение») , в то время как простой массив имеет один, и 1. который не представляет никакой косвенности: он просто псевдоним одного целого)

0

По вопросам рекламы [email protected]