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

Как узнать длину динамического массива c

  • автор:

Узнать длину динамического массива

Здравствуйте! В интернете никак не могу найти способ, который бы позволил найти длину динамического массива без использования каких-либо библиотек(типа Vector и прочее). Скажите, можно ли как-то не используя vector найти длину массива?

1 2 3 4 5
int num_elem; cout"Tell me number of elements "; cin>>num_elem; int *array = new int[num_elem]; cout  "Length of array = "  (sizeof(array)/sizeof(*array))  endl;

То есть , что-то типа такого, как я написал выше. Заранее спасибо!
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:

Как узнать длину строки у двумерного динамического массива
Выделаю память для строк столбцов массива так: int n=11; int **mas = new int *; .

Как подсчитать длину динамического массива?
Лирическое отступлене: С++ мне не нравиться уж больно кривой язык и майкрасофт и борланд как то.

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

Как узнать длину массива?
Функция в качестве параметра получает массив BYTE*. Как узнать его длину?

Как узнать длину динамического или неопределенного массива типа char

Много всего перерыл в интернете, но толкового ответа не нашлось. Знаю что есть sizeof() , который узнает длину статического массива в байтах, но с динамикой это не подходит. Кто знает, подскажите. Например, в этом коде:

char a[] = ""; std::cin >> getline(a, тут_надо_размер); std::cout  

Получается несостыковка: размер мы не знаем, но если я введу фразу "Hello World", как узнать на этапе обработки сколько мне нужно байт?

Отслеживать
9,356 4 4 золотых знака 40 40 серебряных знаков 56 56 бронзовых знаков
задан 4 апр 2015 в 11:10
3,913 7 7 золотых знаков 45 45 серебряных знаков 85 85 бронзовых знаков

Это ужасно, когда пытаются писать на языке без его малейшего понимания. Прочтите K&R для начала, а потом уже программируйте. Без обид.

7 апр 2015 в 13:06

4 ответа 4

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

А не будет оно работать. Так по стандарту. Нужен размер - сохраняйте в отдельной переменной размер. В случае обычных строк в самый конец добавляют ноль, поэтому функции вида strlen и могут получить размер, сканируя строку на наличние нужного символа.

В целом, есть всякие обходные пути "доставания размера", но они сильно зависят от конкретной версии компилятора и даже его настроек. Обычно ими пользуются отладчики.

Пример, который Вы привели, обычно пишут так

#define SIZE 250 std::char a[SIZE]; std::cin.getline(a, SIZE); std::cout  

Но в С++ эту проблему решили - там есть класс std::vector. Используйте его там, где хотите "динамические массивы".

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

Как узнать длину динамического массива c

Кроме отдельных динамических объектов в языке C++ мы можем использовать динамические массивы. Для выделения памяти под динамический массив также используется оператор new , после которого в квадратных скобках указывается, сколько массив будет содержать объектов:

int *numbers ; // динамический массив из 4 чисел // или так // int *numbers = new int[4];

Причем в этом случае оператор new также возвращает указатель на объект типа int - первый элемент в созданном массиве.

В данном случае определяется массив из четырех элементов типа int, но каждый из них имеет неопределенное значение. Однако мы также можем инициализировать массив значениями:

int *numbers1 >; // массив состоит из чисел 0, 0, 0, 0 int *numbers2 >; // массив состоит из чисел 1, 2, 3, 4 int *numbers3 >; // массив состоит из чисел 1, 2, 0, 0 // аналогичные определения массивов // int *numbers1 = new int[4]<>; // массив состоит из чисел 0, 0, 0, 0 // int *numbers1 = new int[4](); // массив состоит из чисел 0, 0, 0, 0 // int *numbers2 = new int[4]< 1, 2, 3, 4 >; // массив состоит из чисел 1, 2, 3, 4 // int *numbers3 = new int[4]< 1, 2 >; // массив состоит из чисел 1, 2, 0, 0

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

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

int *numbers >; // массив состоит из чисел 1, 2, 3, 4

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

int *numbers >; // получение элементов через синтаксис массивов std::cout 

Причем для доступа к элементам динамического массива можно использовать как синтаксис массивов ( numbers[0] ), так и операцию разыменования ( *numbers )

Соответственно для перебора такого массива можно использовать различные способы:

unsigned n< 5 >; // размер массива int* p < new int[n] < 1, 2, 3, 4, 5 >>; // используем индексы for (unsigned i<>; i < n; i++) < std::cout std::cout ; i < n; i++) < std::cout std::cout ; q != p + n; q++) < std::cout std::cout 

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

Для удаления динамического массива и освобождения его памяти применяется специальная форма оператора delete :

delete [] указатель_на_динамический_массив;

#include int main() < unsigned n< 5 >; // размер массива int* p < new int[n] < 1, 2, 3, 4, 5 >>; // используем индексы for (unsigned i<>; i < n; i++) < std::cout std::cout

Чтобы после освобождения памяти указатель не хранил старый адрес, также рекомендуется обнулить его:

delete [] p; p = nullptr; // обнуляем указатель

Многомерные массивы

Также мы можем создавать многомерные динамические массивы. Рассмотрим на примере двухмерных массивов. Что такое по сути двухмерный массив? Это набор массив массивов. Соответственно, чтобы создать динамический двухмерный массив, нам надо создать общий динамический массив указателей, а затем его элементы - вложенные динамические массивы. В общем случае это выглядит так:

#include int main() < unsigned rows = 3; // количество строк unsigned columns = 2; // количество столбцов int** numbers>; // выделяем память под двухмерный массив // выделяем память для вложенных массивов for (unsigned i<>; i < rows; i++) < numbers[i] = new int[columns]<>; > // удаление массивов for (unsigned i<>; i < rows; i++) < delete[] numbers[i]; >delete[] numbers; >

Вначале выделяем память для массива указателей (условно таблицы):

int** numbers>;

Затем в цикле выделяем память для каждого отдельного массива (условно строки таблицы):

numbers[i] = new int[columns]<>;

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

Пример с вводом и выводом данных двухмерного динамического массива:

#include int main() < unsigned rows = 3; // количество строк unsigned columns = 2; // количество столбцов int** numbers>; // выделяем память под двухмерный массив for (unsigned i<>; i < rows; i++) < numbers[i] = new int[columns]<>; > // вводим данные для таблицы rows x columns for (unsigned i<>; i < rows; i++) < std::cout ; j < columns; j++) < std::cout > numbers[i][j]; > > // вывод данных for (unsigned i<>; i < rows; i++) < // выводим данные столбцов i-й строки for (unsigned j<>; j < columns; j++) < std::cout std::cout for (unsigned i<>; i < rows; i++) < delete[] numbers[i]; >delete[] numbers; >

Пример работы программы:

Enter data for 1 row 1 column: 2 2 column: 3 Enter data for 2 row 1 column: 4 2 column: 5 Enter data for 3 row 1 column: 6 2 column: 7 2 3 4 5 6 7

Указатель на массив

От типа int** , который представляет указатель на указатель (pointer-to-pointer) следует отличать ситуацию "указатель на массив" (pointer to array). Например:

#include int main() < unsigned n; // количество строк int (*a)[2] = new int[n][2]; int k<>; // устанавливаем значения for (unsigned i<>; i < n; i++) < // устанавливаем данные для столбцов i-й строки for (unsigned j<>; j < 2; j++) < a[i][j] = ++k; >> // вывод данных for (unsigned i<>; i < n; i++) < // выводим данные столбцов i-й строки for (unsigned j<>; j < 2; j++) < std::cout std::cout // удаляем данные delete[] a; a = nullptr; >

Здесь запись int (*a)[2] представляет указатель на массив из двух элементов типа int. Фактически мы можем работать с этим объектом как с двухмерным массивом (таблицей), только количество столбцов в данном случае фиксировано - 2. И память для такого массива выделяется один раз:

int (*a)[2] = new int[n][2];

То есть в данном случае мы имеем дело с таблице из n строк и 2 столцов. Используя два индекса (для строки и столца), можно обращаться к определенному элементу, установить или получить его значение. Консольный вывод данной программы:

1 2 3 4 5 6

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

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