Указатели массивов, используемые в выражениях, неявно преобразуются (за редкими исключениями, например, при использовании их в операторе sizeof
) в указатели на их первые элементы.
Итак, в этом вызове
print_elemTab(tab);
выражение аргумента имеет тип int *
.
С другой стороны, параметр функции, имеющий тип массива, корректируется компилятором на указатель на тип элемента массива.
Так, например, эти объявления функций
void print_elemTab(int tab[]);
void print_elemTab(int tab[5]);
void print_elemTab(int tab[100]);
объявляют одну и ту же функцию и эквивалентны следующему объявлению
void print_elemTab(int *tab);
Вы даже не можете включить все эти объявления в свою программу, хотя компилятор может выдать сообщение о наличии избыточных объявлений.
Следовательно, внутри функции вы имеете дело с указателем типа int *
. И sizeof( int * )
обычно равно 4
или 8
в зависимости от используемой системы.
Если у вас есть такое объявление, вы должны изменить его, указав второй параметр, который сохранит количество элементов в переданный массив, например
void print_elemTab(int *tab, size_t n );
И функция может вызываться как
print_elemTab(tab, std::size( tab ) );
Другой подход - передать массив по ссылке. В этом случае вы должны объявить шаблонную функцию, например, как
template <size_t N>
void print_elemTab( int ( &tab )[N] );
Внутри функции вы можете либо напрямую использовать параметр шаблона N
как количество элементов в массиве. Или вы можете применить к массиву ту же стандартную функцию C ++ std::size
.
Или функция может быть еще более общей, объявленной со вторым параметром типа шаблона, например
template <typename T, size_t N>
void print_elemTab( T ( &tab )[N] );
Другой подход - для объявления функции типа
template <typename Container>
void print_elemTab( Container &container );
В этом случае вы также можете применить стандартную функцию std::size
к контейнеру параметров.