Страницы

Поиск по вопросам

четверг, 19 декабря 2019 г.

Как узнать размер массива переданного в функцию?

#cpp #c #массивы #указатели #ссылки


Необходимо определить размер массива, переданного в функцию. Пробовал вот так:

void foo(int* Array)
{
    const unsigned int SIZE = sizeof(Array)/sizeof(int);
}


но в SIZE сохраняется 1, независимо от размера массива. Можно, конечно, вместе с
массивом передать в функцию и его размер, но может существует более изящное решение?

P.S.: Кстати, заметил нечто странное. Запускал эту программу через Visual Studio
и Qt. В VS в SIZE сохраняется 1, а в Qt 2.
    


Ответы

Ответ 1



У вас параметр функции foo объявлен как указатель типа int * void foo(int* Array); ^^^^^^^^^^ Следовательно внутри функции выражение sizeof(Array)/sizeof(int) эквивалентно выражению sizeof(int *)/sizeof(int) Если, например, размер указателя, то есть типа int *, равен 8 байтам, а размер типа int равен 4 байтам, то в итоге вы получите 2. Если же при этом размер типа int равен также 8 байтам (64-битовая ОС), то вы получите в итоге 1. Но даже если вы объявите эту функцию как void foo(int Array[]); или даже так void foo(int Array[10]); все равно параметр функции неявно преобразуется в указатель на элемент массива. То есть эти два объявления функции объявляют одну и ту же функцию и эквивалетны следующему объявлению void foo(int* Array); Так что внутри функции вы снова будете иметь дело с указателем. Когда массив передается по значению, то вам следует также объявлять второй параметр, который задает размер массива. Или массив должен иметь некоторый граничный элемент с уникальным значением, по которому можно определить число актуальных элементов, как это имеет место, например, со строками, когда строки завершаются нулем, то есть символом '\0'. То есть в общем случае вам следует объявлять функцию как void foo(int* Array, size_t n); где n - это размер массива. Другой подход - это объявлять параметр как ссылку на массив. В этом случае длина массива будет известна внутри функции. Например void foo( int ( &Array )[10] ) { const size_t = sizeof( Array)/ sizeof( *Array ); } Недостаток этого объявления состоит в том, что эта функция может иметь дело только с массивами, заданного в ее параметре размера. Чтобы обойти это ограничение, вы можете объявить шаблонную функцию. Например, template void foo( int ( &Array )[N] ) { const size_t n = N; } В этом случае компилятор, используя шаблон, создаст столько функций, сколько массивов разной длины были использованы в качестве аргумента.

Комментариев нет:

Отправить комментарий