Если функция имеет параметр массива определенного размера, почему он заменяется указателем?
учитывая следующую программу,
#include <iostream>
using namespace std;
void foo( char a[100] )
{
cout << "foo() " << sizeof( a ) << endl;
}
int main()
{
char bar[100] = { 0 };
cout << "main() " << sizeof( bar ) << endl;
foo( bar );
return 0;
}
выходы
main() 100
foo() 4
- почему массив передается как указатель на первый элемент?
- это наследие от C?
- что говорит стандарт?
- почему строгая тип-безопасность C++ отброшена?
3 ответа:
Да он унаследован от C. функция:
void foo ( char a[100] );
будет иметь параметр, настроенный как указатель, и так становится:
void foo ( char * a );
если вы хотите, чтобы тип массива был сохранен, Вы должны передать ссылку на массив:
void foo ( char (&a)[100] );
C++ ' 03 8.3.5 / 3:
...Тип функции определяется с помощью следующих правил. Тип каждого параметра определяется по-своему Децл-спецификатор-seq и Декларатор. После определения типа каждого параметра любой параметр типа "массив T" или "функция, возвращающая T" настраивается как "указатель на T" или "указатель на функцию, возвращающую T" соответственно....
чтобы объяснить синтаксис:
Проверьте правило "справа налево" в google; я нашел одно его описание здесь.
это было бы применено к этому примеру примерно как следует:
void foo (char (&a)[100]);
начните с идентификатора "a"
' a ' - это
двигаемся вправо-находим
)
Итак, мы меняем направление поиска(
. Когда мы двигаемся влево, мы проходим&
'a' - это ссылка
после
&
мы достигаем открытия(
Итак, мы снова разворачиваемся и смотрим направо. Теперь мы видим[100]
'a' - это ссылка на массив 100
и мы снова меняем направление, пока не достигнем
char
:" a " - это ссылка на массив из 100 символов
да. В C и C++ нельзя передавать массивы в функции. Вот только так оно и есть.
почему вы делаете простые массивы в любом случае? Вы смотрели на
boost
/std::tr1::array
/std::array
илиstd::vector
?обратите внимание, что вы можете, однако, передать ссылку на массив произвольной длины, чтобы функция шаблон. С верхней части моей головы:
template< std::size_t N > void f(char (&arr)[N]) { std::cout << sizeof(arr) << '\n'; }
в терминологии C/C++ есть великолепное слово, которое используется для статических массивов и указателей функций -распад. Рассмотрим следующий код:
int intArray[] = {1, 3, 5, 7, 11}; // static array of 5 ints //... void f(int a[]) { // ... } // ... f(intArray); // only pointer to the first array element is passed int length = sizeof intArray/sizeof(int); // calculate intArray elements quantity (equals 5) int ptrToIntSize = sizeof(*intArray); // calculate int * size on your system