Как узнать размер массива c
Перейти к содержимому

Как узнать размер массива c

  • автор:

Найдите размер массива в C, используя оператор sizeof и арифметику указателя

В этом посте представлен обзор некоторых доступных альтернатив для определения размера массива в C.

1. оператор sizeof

Стандартным способом является использование sizeof оператор, чтобы найти размер массива в стиле C. sizeof Оператор над массивом возвращает общую память, занимаемую массивом, в байтах. Чтобы определить общее количество элементов массива, трюк состоит в том, чтобы разделить общую память, занимаемую массивом, на размер каждого элемента. Это показано ниже на языке C:

int main ( void )
size _ т n = sizeof ( arr ) / sizeof ( arr [ 0 ] ) ;
printf ( «The size of the array is %d» , n ) ;

Для простоты и улучшения читаемости кода предлагается сконструировать из него МАКРОС, как показано ниже:

#define SIZEOF(a) sizeof(a)/sizeof(*a)
int main ( void )
size _ т n = SIZEOF ( arr ) ;
printf ( «The size of the array is %d» , n ) ;

Мы знаем, что массив распадается на указатель при передаче функции в качестве аргумента независимо от того, объявлен ли параметр как int[] или нет. Таким образом, описанный выше подход работает только со статическими массивами, но не работает с динамически выделенными массивами и параметрами функций, поскольку они оба включают указатели.

#define N 5
// массив распадается на указатель
size_t getSize ( int * arr )
size _ т n = sizeof ( arr ) / sizeof ( arr [ 0 ] ) ;
int main ( void )
int * a = malloc ( N * sizeof ( int ) ) ;
printf ( «%zu\n» , sizeof ( a ) / sizeof ( a [ 0 ] ) ) ; // это не сработает
printf ( «%zu\n» , getSize ( b ) ) ; // это не сработает

2. Использование арифметики указателей

Хитрость заключается в использовании выражения (&arr)[1] — arr чтобы получить массив arr размер. Оба arr а также &arr указывает на одну и ту же ячейку памяти, но они оба имеют разные типы.

  1. arr имеет тип int* и распадается на указатель на первый элемент массива. Следовательно, любые знания о размере массива исчезли.
  2. &arr приводит к указателю типа int (*)[n] , то есть указатель на массив n целые Так, &arr указывает на весь массив и *(&arr + 1) (или же &arr)[1] ) указывает на следующий байт после массива.

Это работает благодаря тому, как работает арифметика указателей в C. Мы знаем, что указатель на int продвигается sizeof(int) при увеличении на 1. Точно так же указатель на int[n] продвигается sizeof(int[n]) , что является размером всего массива.

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

но в SIZE сохраняется 1, независимо от размера массива. Можно, конечно, вместе с массивом передать в функцию и его размер, но может существует более изящное решение? P.S.: Кстати, заметил нечто странное. Запускал эту программу через Visual Studio и Qt. В VS в SIZE сохраняется 1, а в Qt 2.

Отслеживать
44.8k 3 3 золотых знака 38 38 серебряных знаков 89 89 бронзовых знаков
задан 14 окт 2016 в 13:34
130 1 1 золотой знак 1 1 серебряный знак 8 8 бронзовых знаков
sizeof(Array) — размер указателя на int в данном случае.
14 окт 2016 в 13:37
При имеющейся сигнатуре размер массива Вы узнать не сможете.
14 окт 2016 в 13:38

А при чём тут C++? Размер массива в C++ узнать очень просто: методом size() (если это, скажем, vector ) или аналогичным.

14 окт 2016 в 13:40

@PinkTux так вопрос про обычные массивы, не STL-контейнеры же. Хотя согласен, в С++ по возможности стоит отказываться от сишных массивов в пользу vector, array и прочего.

14 окт 2016 в 13:42
Вот еще может помочь
14 окт 2016 в 13:42

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

У вас параметр функции 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] )

В этом случае компилятор, используя шаблон, создаст столько функций, сколько массивов разной длины были использованы в качестве аргумента.

Как определить длину массива в C++

По сути, когда мы говорим о длине массива, мы имеем в виду общее количество элементов, присутствующих в соответствующем массиве. Например, посмотрите на массив ниже:

int array1[] =

Размер (или длина) массива равна общему количеству элементов в нем. Следовательно, в данном случае это «5».

Способы определения длины массива в C++

Теперь давайте посмотрим на различные способы, с помощью которых мы можем выяснить длину массива в C++:

  • поэлементный подсчет,
  • begin() и end(),
  • функция sizeof(),
  • функция size() в STL,
  • указатели.

Теперь давайте обсудим каждый метод подробно и с примерами.

1: Поэлементный подсчет

Самый очевидный способ – перебрать заданный массив и одновременно подсчитать общее количество перебранных элементов.

Но если мы заранее не знаем длину массива для итерации, то в таком случае мы не можем использовать цикл for. Эту проблему можно решить, используя простой цикл for-each. Внимательно посмотрите на приведенный ниже код.

#include #include using namespace std; int main() < int c; int arr[]=; cout cout

Вы получите такой результат:

The array is: 1 2 3 4 5 6 7 8 9 0 The length of the given Array is: 10

Как мы говорили выше, здесь мы перебираем весь массив arr, используя цикл for-each с итератором i. Значение счетчика c увеличивается по мере итерации. Когда перебор закончится, в c вы найдете длину данного массива.

2: Функции begin() и end()

Мы также можем вычислить длину массива, используя стандартные функции begin() и end(). Эти две функции возвращают итераторы, указывающие на начало и конец массива соответственно. Внимательно посмотрите на данный код:

#include #include using namespace std; int main() < //Given Array int arr[] = < 11, 22, 33, 44 >; cout

Следовательно, разница между возвращаемыми значениями двух функций end() и begin() дает нам размер или длину данного массива. Данный код вернет:

The Length of the Array is : 4

3: Функция sizeof()

Оператор sizeof() в C++ возвращает размер переданной переменной или данных в байтах. Кроме того, он возвращает общее количество байтов, необходимых для хранения массива. Следовательно, если мы просто разделим размер массива на размер, занимаемый каждым его элементом, мы узнаем общее количество элементов, присутствующих в массиве.

Давайте посмотрим, как это работает:

#include #include using namespace std; int main() < //Given array int arr[] = ; int al = sizeof(arr)/sizeof(arr[0]); //length calculation cout

В результате мы получим:

The length of the array is: 3

4: Функция size() в STL

В стандартной библиотеке есть функция size(), которая возвращает количество элементов в заданном контейнере (в нашем случае это массив).

#include #include using namespace std; int main() < //Given array arrayarr< 1, 2, 3, 4, 5 >; //Using the size() function from STL cout

В результате вы получите:

The length of the given Array is: 5

5: Определение длины массива с помощью указателей

Узнать длину массива можно с помощью указателей. Давайте посмотрим, как это делается:

#include #include using namespace std; int main() < //Given array int arr[6] = ; int len = *(&arr + 1) - arr; //*(&arr + 1) is the address of the next memory location // just after the last element of the array cout

В результате мы получим:

The length of the array is: 6

Выражение *(arr+1) выдает адрес области памяти сразу после последнего элемента массива. Следовательно, разница между ним и начальным местоположением массива (или базовым адресом, arr) показывает общее количество элементов, присутствующих в данном массиве.

Заключение

Итак, в этом мануале мы обсудили различные методы определения длины массива в C++. Все приведенные выше методы просты в использовании, однако мы предпочитаем применять цикл for-each – не только из-за удобочитаемости кода, но и из-за его кросс-платформенной надежности.

Узнать размер массива по указателю

Всегда выодится 8. Не могу понять почему. В нете пишуть мутно либо — нельзя.
Так все-таки, можно узнать размер массива по указателю?

94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:

Узнать размер памяти по указателю с помощью IntPtr.Size
Создаю объект IntPtr contourVs = CvInvoke.cvCreateMemStorage(0); //и выполняю с ним несколько.

Размер массива по указателю
Не уверен, что всё правильно понимаю. Про "new" пишут, что оно выделяет необходимое количество.

Определить размер массива по указателю
Собственно вопрос в следующем: можно ли определить размер выделенного динамически массива по.

Ушел с форума

Эксперт С++

16470 / 7433 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1

ЦитатаСообщение от animator404 Посмотреть сообщение

Всегда выодится 8. Не могу понять почему.

Массив при передаче в функцию вырождается в указатель.
Т.е. «sizeof (args)» внутри printArrrSize случае всегда будет равен «sizeof (void *)».

ЦитатаСообщение от animator404 Посмотреть сообщение

Так все-таки, можно узнать размер массива по указателю?
Никак. Язык не предоставляет такой возможности.

Эксперт CАвтор FAQ

21275 / 8292 / 637
Регистрация: 30.03.2009
Сообщений: 22,656
Записей в блоге: 30

ЦитатаСообщение от animator404 Посмотреть сообщение

Так все-таки, можно узнать размер массива по указателю?

В таких случаях есть два стандартных способа:
1. Размер передавать отдельным параметром
2. Последним элементом массива записывать специальное заранее оговоренное значение, которое функция будет трактовать как конец массива (при обходе всех элементов, начиная с первого)

В большинстве случаев пользуется первым

87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь

Как узнать значение массива по указателю во время отладки?
А как посмотреть значения массива, если есть только указатель на его первый элемент? Например: .

Узнать размер массива
есть 2 указателя на первый элемент массива и указатель на элемент после последнего можно ли.

Как узнать размер массива?
Имею функцию template <typename T> int funk(T mas, T element) < //kod >

Узнать размер динамического массива
Здравствуйте. Пытаюсь сделать динамический массив и вывести его размерность. Выводится размерность.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *