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

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

  • автор:

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

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

Отслеживать
44.8k 3 3 золотых знака 39 39 серебряных знаков 90 90 бронзовых знаков
задан 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

Массив представляет набор однотипных данных. Формальное определение массива выглядит следующим образом:

тип_переменной название_массива [длина_массива]

После типа переменной идет название массива, а затем в квадратных скобках его размер. Например, определим массив из 4 чисел:

int numbers[4];

Число элементов массива также можно определять через константу:

const int n = 4; int numbers[n]; // содержит 4 элемента

Некоторые компиляторы (например, G++) также поддерживают установку размера с помощью переменных.

Данный массив имеет четыре числа, но все эти числа имеют неопределенное значение. Чтобы установить значения элементов массива, указываются фигурные скобки (инициализатор), внутри которых перечисляются значения для элементов массива:

int numbers[4] <>; //

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

Также мы можем указать конкретные значения для всех элементов массива:

int numbers[4] ;

В данном случае в памяти выделяется некоторая область из четырех ячеек по 4 байта (размер типа int), где каждая ячейка содержит определенный элемент массива:

Если значений в инициализаторе меньше, чем элементов в массиве, то значения передаются первым элементам, а остальные получают нулевые значения:

int numbers[4] ; //

Если значений в инициализаторе больше, чем элементов в массиве, то при компиляции возникнет ошибка:

int numbers[4] ; // ! Ошибка

Здесь массив имеет размер 4, однако ему передается 6 значений.

Если размер массива не указан явно, то он выводится из количества переданных значений:

int numbers[] ;

В данном случае в массиве есть 6 элементов.

При этом не допускается присвоение одному массиву другого массива:

int nums1[] ; int nums2[] = nums1; // ошибка

Индексы. Получение и изменение элементов массива

После определения массива мы можем обратиться к его отдельным элементам по индексу. Индексы начинаются с нуля, поэтому для обращения к первому элементу необходимо использовать индекс 0. Обратившись к элементу по индексу, мы можем получить его значение, либо изменить его. Например, получим второй элемент (индекс 1):

int n = numbers[1];

Изменение значения второго элемента:

numbers[1] = 123;

Например, получим и изменим значения элементов:

#include int main() < int numbers[4]; int first = numbers[0]; // получаем первый элемент std::cout 

При обращении по индексу следует учитывать, что мы не можем обратиться по несуществующему индексу. Так, если в массиве 4 элемента, то мы можем использовать индексы с 0 до 3 для обращения к его элементам. Использование любого другого индекса приведет к ошибке:

int numbers[4]; int forth = numbers[4]; // !Ошибка - в массиве только 4 элемента

Константные массивы

Если необходимо, чтобы нельзя было изменять значения элементов массива, то такой массив можно определить как константный с помощью ключевого слова const

const int numbers[4]; // numbers[1] = 23; // ошибка - значения элементов массива изменить нельзя

Длина массива

Длина массива не всегда бывает известна. Однако может потребоваться получить ее. Для этого можно использовать несколько способов. Первый способ, который пришел из языка С, представляет применение оператора sizeof :

#include int main() < int numbers[]; std::cout 

По сути длина массива равна совокупной длине его элементов. Все элементы представляют один и тот же тип и занимают один и тот же размер в памяти. Поэтому с помощью выражения sizeof(numbers) находим длину всего массива в байтах, а с помощью выражения sizeof(numbers[0]) - длину одного элемента в байтах. Разделив два значения, можно получить количество элементов в массиве.

Второй способ представляет применение встроенной библиотечной функции std::size() :

#include int main() < int numbers[]; int count = std::size(numbers); std::cout 

Перебор массивов

Используя циклы, можно пробежаться по всему массиву и через индексы обратиться к его элементам:

#include int main() < const int n = 4; int numbers[n] ; for(int i=0; i < n; i++) < std::cout >

Чтобы пройтись по массиву в цикле, надо знать его длину. Здесь длина задана константой n.вначале надо найти длину массива. И в цикле for перебираем все элементы, пока счетчик i не станет равным длине массива. В итоге на консоль будут выведены все элементы массива:

11 12 13 14

Другой пример - вычислим сумму элементов массива:

#include int main() < int numbers[]; int sum <>; for (int i <>; i < std::size(numbers); sum += numbers[i++]); std::cout 

Здесь длина массива вычисляется динамически - с помощью функции std::size() .

Перебор элементов в стиле for-each

Используем другую форму цикла for , которая предназначена специально для перебора последовательностей, в том числе для массивов

#include int main() < int numbers[4] ; for(int n : numbers) < std::cout >

При переборе массива каждый перебираемый элемент будет помещаться в переменную number, значение которой в цикле выводится на консоль.

Если нам неизвестен тип объектов в массиве, то мы можем использовать спецификатор auto для определения типа:

for(auto n : numbers)

Ввод значений массива с консоли

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

#include int main() < const int max ; // максимальная длина массива - не больше 6 чисел int numbers[max]; // массив для ввода чисел int i<>; // счетчик введенных чисел std::cout > numbers[i]; // вводим число i++; > // выводим массив for (i =0; i < max; ++i) < std::cout std::cout

Здесь в цикле сначала вводятся шесть чисел для каждого элемента массива, затем выводим этот массив.

Найти длину массива в C++

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

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

int array1[] =

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

Способы найти длину массива в C++

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

  1. Поэлементный подсчет
  2. begin() и end() , функция
  3. sizeof() , Функция
  4. size() в STL,
  5. Указатели.

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

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 
The Length of the Array is : 4 

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

3. Использование функции sizeof() для определения длины массива в C++

Оператор 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. Использование указателей для определения длины массива в C++

Мы также можем найти длину данного массива с помощью указателей. Давайте посмотрим, как

#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. Не только из-за удобочитаемости кода, но и из-за его кросс-платформенной надежности.

Если у вас возникнут дополнительные вопросы, не стесняйтесь использовать комментарии ниже.

Рекомендации

  • Как найти длину массива? – Вопрос о переполнении стека,
  • цикл for-each в C++ — сообщение JournalDev.

C++, можно ли узнать размер массива ?

а размер можно узнать, если ты позаботился о том что последний элемент NULL, если нет, то увы но никак.

ну а как в плюсах, точнее что есть в stl не знаю.

alphex_kaanoken ★★★
( 06.12.06 17:57:29 MSK )
Ответ на: комментарий от alphex_kaanoken 06.12.06 17:57:29 MSK

>размер можно узнать, если ты позаботился о том что последний элемент NULL, если нет, то увы но никак.
А в массиве в качестве значения NULL содержаться конечно не может.
К тому же это тогда обязательно должен быть массив указателей.

andron01
( 06.12.06 18:57:16 MSK )
Ответ на: комментарий от andron01 06.12.06 18:57:16 MSK

>А в массиве в качестве значения NULL содержаться конечно не может.

wtf? указатель это указатель. если у нас указатель на указатель то да нужно последним делать NULL. а в случае int* лучше держать например первым элементом количество элементов за ним замаллоченным, или отдельной переменной, не делать же лимитирующим значением 0 ?

к примеру если у меня по указателю находятся какие нить значение, например колебания того или иного, которые могут быть 0.

в случае с int[] уже выше показали как узнать.

alphex_kaanoken ★★★
( 06.12.06 19:15:01 MSK )
Ответ на: комментарий от aeuo 06.12.06 17:48:06 MSK

> можно если массива int arr[]

Нельзя. В списке аргументов int arr[] абсолютно равнозначно int *arr.

uj2 ★★★
( 06.12.06 20:09:13 MSK )
Ответ на: комментарий от uj2 06.12.06 20:09:13 MSK

> УКАЗАТЕЛЬ != МАССИВ!

int arr[5]; int *ar; ar = new int[5];

кстати где0то читал что в С массив == указатель .

anonymous
( 06.12.06 20:31:33 MSK )
Ответ на: комментарий от anonymous 06.12.06 20:31:33 MSK

> Забей на массивы (ибо зло) и пользуй std::vector. Там есть size().

anonymous
( 06.12.06 20:32:08 MSK )

Вот есть ещё такой немножко нестандартный подход. #include using std::cout; using std::endl; template void print(int (&arr)[Len]) < for (size_t i = 0; i < Len; ++i) cout int main() < int arr[] = ; print(arr); return 0; >

Legioner ★★★★★
( 06.12.06 21:21:23 MSK )
Ответ на: комментарий от Legioner 06.12.06 21:21:23 MSK

ага. и по одной функции для каждого размера =))

legk
( 06.12.06 22:30:30 MSK )
Ответ на: комментарий от legk 06.12.06 22:30:30 MSK

Зато компилятор может цикл развернуть, да и вообще заинлайнить всё 🙂

А так конечно vector надо пользовать.

Legioner ★★★★★
( 06.12.06 22:50:56 MSK )
Ответ на: комментарий от anonymous 06.12.06 20:31:33 MSK

> объясните разницу: > int arr[5]; int *ar; > ar = new int[5]; > кстати где0то читал что в С массив == указатель .

Не совсем. Имя массива это всегда указатель на ПЕРВЫЙ элемент. Например ты можешь сделать:

int *ma = malloc(5 * sizeof(int)); ma++;

shumer ★
( 07.12.06 13:05:16 MSK )
Ответ на: комментарий от anonymous 06.12.06 20:31:33 MSK

> объясните разницу: > int arr[5]; int *ar; > ar = new int[5]; > кстати где0то читал что в С массив == указатель . Не совсем. Имя массива это всегда указатель на ПЕРВЫЙ элемент. Например ты можешь сделать: int *ma = malloc(5 * sizeof(int)); ma++; Но нельзя: int a[] = ; a++;

shumer ★
( 07.12.06 13:06:19 MSK )
Ответ на: комментарий от shumer 07.12.06 13:06:19 MSK

> Имя массива это всегда указатель на ПЕРВЫЙ элемент.

Не всегда. Как раз в случаях операций ++ -- sizeof x= . массив не генерирует указателя, а является немодифицируемым lvalue.

uj2 ★★★
( 07.12.06 19:50:54 MSK )
Ответ на: комментарий от uj2 07.12.06 19:50:54 MSK

Вобщем, как говорил Пендальф, нужно обратиться к первоисточнику:

A7.1. Генерация указателя

Если тип выражения или подвыражения есть "массив из T", где T - некоторый тип, то значением этого выражения является указатель на первый элемент массива, и тип такого выражения заменяется на тип "указатель на T". Такая замена не делается, если выражение является операндом унарного оператора &, или операндом операций ++, --, sizeof, или левым операндом присваивания, или операндом оператора . (точка). Аналогично, выражение типа "функция, возвращающая Т", кроме случая, когда оно является операндом для &, преобразуется в тип "указатель на функцию, возвращающую T".

shumer ★
( 07.12.06 21:15:01 MSK )
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.

Похожие темы

  • Форум [C++] массивы и указатели (2010)
  • Форум [C]Подскажите как компилер обязан передавать массивы в ф-ю (2008)
  • Форум Многомерные массивы и указатели в ANSI C (2016)
  • Форум Печать массива символов. (2014)
  • Форум Сумма чисел двумерного массива во время компиляции (2018)
  • Форум bash. массивы. не понятка с размером массива. (2012)
  • Форум Ссылки на элементы массива в PHP (2012)
  • Форум Задачка с массивом строк на Си (2008)
  • Форум Странность с массивом нулевой длины в C++ (2016)
  • Форум Изменение размера массива по указателю (2018)

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

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