Если функция имеет параметр массива определенного размера, почему он заменяется указателем?


учитывая следующую программу,

#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
  1. почему массив передается как указатель на первый элемент?
  2. это наследие от C?
  3. что говорит стандарт?
  4. почему строгая тип-безопасность C++ отброшена?
3 58

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