Страницы

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

пятница, 5 апреля 2019 г.

Некорректный вывод размерности массива в функции [дубликат]

На данный вопрос уже ответили: Передача статического одномерного массива определённого размера в функцию 6 ответов Уважаемые коллеги!
Компилятор меня не понимает. Общеизвестно, что размерность массива int size = (sizeof(b) / sizeof(*b));Где, b - некоторый массив. Так вот в примере ниже я получаю размерность массива вынося эту команду в отдельную функцию и выполняя эту команду в main
#include "stdafx.h" #include #include
using namespace std;
//Функция которая считает и печатает размерность массива. void ArrLength(int a[]) { int j = (sizeof(a) / sizeof(*a));; //определяем размерность массива cout << "Размерность массива в функции ArrLength = " << j << endl; }
int main() { setlocale(LC_ALL, "Russian");
int b[] = {3, 5, 8, 3, 0, 32, 18, 65}; //объявление некоторого массива int size = (sizeof(b) / sizeof(*b)); //выяснение размерности некоторого массива cout << "Размерность массива size = " << size << endl; ArrLength(b);
system("PAUSE"); return 0; }
К моему глубочайшему удивлению, распечатывает:
Размерность массива size = 8 Размерность массива в функции ArrLength = 2
То есть, даёт два различных ответа. И если с первым я готов согласиться, то второй кажется мне явно ошибочным.
Вопрос: чем можно объяснить наблюдаемое поведение?


Ответ

Параметры функции, объявленные как массивы, неявно упорядочиваются в указатели на типы элементов массивов.
Поэтому следующие объявления функции
void ArrLength(int a[]); void ArrLength(int a[100]); void ArrLength(int *a);
Эквивалентны и объявляют одну и туже функцию, параметром которой будет указатель типа int *
Вы все эти объявления можете одновременно включить в программу, так как одну и ту же функцию можно объявлять (в отличии от определения функции) несколько раз.
Поэтому внутри этой функции
void ArrLength(int a[]) { int j = (sizeof(a) / sizeof(*a));; //определяем размерность массива cout << "Размерность массива в функции ArrLength = " << j << endl; }
параметр функции a имеет тип int * и выражение
sizeof(a) / sizeof(*a)
эквивалентно выражению
sizeof( int * ) / sizeof( int )
и в зависимости от платформы будет равно либо 2 либо 1.
Если вы хотите написать самостоятельно функцию, которая будет возвращать число элементов в массиве, то вам следует написать шаблонную функцию, в которой массив передается по ссылке.
Например
template size_t ArrLength( const T (&a)[N] ) { return N; }
В С++ вы можете воспользоваться структурой std::extent для получения количества элементов в массиве. Например,
#include #include
int main() { int a[4][6];
std::cout << std::extent::value << std::endl; std::cout << std::extent::value << std::endl; }
Вывод программы на консоль
4 6

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

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