Может ли указатель преобразоваться в массив во время вызова функции?
Нет. См. Последний пример при передаче по ссылке.
Тип массива имеет размер (который включает в себя все элементы). Когда он превращается в указатель, эта информация о размере теряется. Поэтому нет способа конвертировать указатель обратно в массив (поскольку вы не знаете, насколько велик массив).
Вы, вероятно, заметили, что параметры массива и указателя на самом деле являются синонимами для компилятора:
> cat b.cpp
void use_pointer(int *ptr)
{}
void use_pointer(int (arr)[])
{}
> g++ b.cpp
b.cpp:8:6: error: redefinition of 'use_pointer'
void use_pointer(int (arr)[])
^
b.cpp:4:6: note: previous definition is here
void use_pointer(int *ptr)
Для компилятора не имеет значения, что это одно и то же.
Таким образом, когда вы передаете массив в качестве параметра, он обычно затухает в указатель (для адреса первого элемента массива).
Теперь вы можете передавать массив по ссылке, но синтаксис другой.
void use_pointerref(int (&arr)[1]) // You have to specify the exact size
{} // And lace the ampersand in there.
Но вы заметите, что указатель не будет привязываться к этой функции.
use_arrayref(arr);
use_arrayref(ptr);
> g++ b.cpp
b.cpp:31:5: error: no matching function for call to 'use_arrayref'
use_arrayref(ptr);
^~~~~~~~~~~~
b.cpp:14:6: note: candidate function not viable: no known conversion from
'int *' to 'int (&)[1]' for 1st argument
void use_arrayref(int (&arr)[1])
Некоторые заметки:
Но давайте подумаем об этом. Семантика C ++ обычно передается по значению. Поэтому, если бы вам удалось (или я должен сказать, если язык позволял) передать массив, вы бы сделали копию массива, который был бы передан функции. Это, вероятно, нежелательно, поэтому использование указателя - эффективный способ передачи по значению (хотя вы и получаете изменение типа).
Обратите внимание, что передача по ссылке очень ограничена, поскольку она должна знать точный тип. Мы обычно решаем проблему размера, делая ее шаблоном.
template<int S>
void use_pointerref(int (&arr)[S])
{
std::cout << typeid(arr).name() << " Size: " << S << std::endl;
}