Как сделать массив с неизвестным количеством элементов с

Добавил пользователь Алексей Ф.
Обновлено: 04.10.2024

Этот вариант походит для одномерного массива.
Если попробовать вставлять длементы с двумя интедксами , то система пишет "Индекс находится за границами массива", а если сделать так Переменная = Новый Массив (10, 10) то все работает.

(4) А вы точно в 1с хотите многомерные массивы?)
Наверное это настолько не нужно что никто об этом даже не подумал.
Если не секрет, в рамках какой задачи это потребуется?

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

Давайте я опиши задачу полностью может ее лучше делать не через массив.
- Есть Excel-файл. Из него надо импортировать данные в табличную часть документа (примерно половина полей).
- Для того чтобы сформировать втору часть ТЧ мне необходимо при помощи запроса "присобачить" данные из связанных данных.
По отдельности все работает, а вот слить все вместе я хотел через массив.
Есть ли другие варианты решения?

Вот как я могу ввести массив, когда мы знаем размер n , Но когда мы не знаем размер n и мы должны принять входные данные в массив и прекратить принимать входные данные, когда появляется новая строка. Как мы можем сделать это в C ++?

Решение

std::vector это то, что вам нужно. Думайте об этом как о массиве динамического размера.

Вы можете добавить элементы в вектор с помощью .push_back()

Другие решения

Чтобы прекратить принимать ввод, вам нужно использовать EOF Concept. конец файла. Поместите контейнер в петлю.
Что-то вроде этого —

Так что это мешает вам делать проверку ошибок, но по крайней мере для моих игрушечных проектов стоит использовать vector с istream_iterator Так что-то вроде этого:

Вам, вероятно, понадобится вектор типа string если вы не используете stoi();
Так что в основном что-то вроде кода ниже.

Вместо введения

Допустим, у вам необходимо хранить в вашей программе 10 целочисленных значений. С одной стороны, если вам не лень (и не жалко тех, кто будет смотреть Ваш код) вы можете объявить 10 переменных типа int , инициализировать их и работать. А что делать, если требуется 100 значений или 1000? Опять же, можно сходить с ума и заводить под каждое значение отдельную переменную, а можно сделать проще — объявить переменную-массив и хранить в ней все значения.

где Type — это тип элементов массива, а ArrayName — его имя. То есть, визуально, массив от обычной переменной отличает наличие после названия типа данных квадратных скобок. Например, вот так можно определить массив целых чисел типа int :

Так можно объявить массивы строк и вещественных чисел:

Например, создадим массив, который будет хранить 5 чисел типа int :

В цикле foreach

Выше я показал один из способов как перебрать элементы массива с использованием цикла foreach :

Здесь в цикле foreach мы указали тип элементов int , так как у нас массив содержит элементы этого типа и после ключевого слова in указали массив элементы которого необходимо перебрать. Если бы у нас был массив строк, то цикл выглядел бы, соответственно, следующим образом:

Цикл foreach достаточно удобный для работы, но иногда бывает так, что возможностей цикла не достаточно. Например, мы создаем массив и нам требуется обеспечить доступ только к элементам с чётными индексами (0, 2, 4, 6 и т.д.). Технически, мы можем использовать тот же foreach , ввести дополнительную переменную и с помощью неё проверять какой индекс у очередного элемента, но это усложнит наш код. Более гибким в этом плане является цикл for в котором мы можем задавать порядок выполнения.

В цикле for

С этим циклом мы тоже уже знакомы. Попробуем реализовать озвученный выше вариант перебора элементов массива — прочитать значения только элементов с чётными индексами. С циклом for это можно сделать, например, вот так:

Вывод консоли будет выглядеть следующим образом:

Счётчик цикла: 1. Читаем элемент с индексом 2 значение: 16

Счётчик цикла: 2. Читаем элемент с индексом 4 значение: -12

Счётчик цикла: 3. Читаем элемент с индексом 6 значение: 80

Счётчик цикла: 4. Читаем элемент с индексом 8 значение: 90

Счётчик цикла: 5. Читаем элемент с индексом 10 значение: 102

Условие в теле цикла:

Требуется для того, чтобы мы не вышли за границы массива. Так, уже на шестом шаге цикла мы бы получили то, что должны прочитать элемент с индексом 6*2=12 которого не существует (максимальный индекс у нас в примере — 10 ) и программа бы выдала нам исключение:

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

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

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

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

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

Название Тип данных Описание
Length int Возвращает общее число элементов во всех измерениях массива
Rank int Получает ранг (число измерений) массива
Long Length long Возвращает 64-разрядное целое число, представляющее общее число элементов во всех измерениях массива
Название Тип данных Описание
Get Length() int Возвращает 32-разрядное целое число, представляющее количество элементов в заданном измерении массива
Get Lower Bound() int Получает Индекс первого элемента заданного измерения в массиве
Get Upper Bound() int Получает Индекс последнего элемента заданного измерения в массиве.

В цикле foreach

Цикл foreach предоставляет нам самый простой и понятный способ доступа к каждому элементы массива. Например, возьмем наш двумерный массив и попробуем перебрать все его элементы в цикле foreach:

В результате, в консоли появится строка, содержащая элементы массива:

В цикле for

здесь в условии цикла мы воспользовались методом GetLength() , чтобы получить количество элементов по первому измерению ( 5 ), а уже в теле цикла получаем значения элементов в каждой строке во втором столбце (помним, что индекс первых элементов в массиве всегда равен 0 ).

Второй вариант — нам надо прочитать значения в последнем столбце массива, но, при этом мы не знаем размерность второго измерения. Чтобы было по-понятнее, я объявил в коде две дополнительные переменные :

В цикле мы запрашиваем элемент с индексами:

Соответственно, если необходимо пройти по всем элементам массива, то можно использовать вложенные циклы for и организовать доступ к элементам массива в любом порядке — построчно, по столбцам…да хоть по диагонали — тут всё будет зависеть от задачи.

Массив массивов — это массив, элементы которого сами являются массивами. Элементы массива массивов могут иметь различные измерения и размеры. Массив массивов также иногда называется нерегулярным или зубчатым массивом. Объявление массива массивов выглядит следующим образом:

Теперь наш массив содержит три массива на 2, 3 и 4 элемента соответственно и каждый из этих массивов будет содержать целые числа. Чтобы заполнить массив значениями элементов, можно воспользоваться любым из способов, которые мы рассмотрели для одномерных массивов, например, так:

Для доступа к элементам массива массивов необходимо использовать вот такую языковую конструкцию:

Неявно типизированные массивы

При этом, если Вы попытаетесь объявить вот такой массив:

Работать с такими массивами можно точно также, как и со всеми другими типами массивов, которые были рассмотрены выше.

Итого

нужно инициализировать и наверное как я понимаю выделить память. Но количество элементов неизвестно. Например, сколько раз пользователь нажмёт кнопку - такая и будет размерность. Как быть в этой ситуации? Память желательно выделять через malloc, а не new


myElements = calloc(number_of_elements, sizeof(Elements))

void *calloc(size_t num, size_t size);

Функция calloc() выделяет память, размер которой равен значению выражения num * size, т.е. память, достаточную для размещения массива, содержащего num объектов размером size. Все биты распределенной памяти инициализируются нулями.


number_of_elements - фиксированный размер массива, а у меня неизвестно сколько элементов будет


>неизвестно сколько элементов будет
размер с неба упадет?


используй списки вместо массивов


>На языке Си при создании максива


man динамические структуры данных


Связный список. А так - читай Кормена или Кнута.


Да и в С++ лучше использовать контейнерные типы из STL - std::vector, std::list. Для C, наверно, стоит использовать glib.


зачем все усложнять(списки строить). используй realloc


+100500
зачем писать велосипеды


голосую за список или статическое аллоцирование памяти большими кусками с запасом(чтобы избежать фрагментации), при нехватке памяти realloc и тоже с запасом.


сессия в августе?


Вообще, если все же не сессия, то для задачи выбран совершенно неподходящий язык(и нет, С++ тоже не подходящий).

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

Love5an демонстрирует чудеса телепатии - определение задачи по одному определению типа!

Использовать связный список, каждый раз добавляя в него элемент, выделенный при помощи malloc(). Дело в том, что realloc() заведомо неэффективен при больших массивах.

Читайте также: