Массивы против векторов: вводные сходства и различия
В чем разница между массивом и вектором в С++? Примером различий могут быть включены библиотеки, символизм, способности и т.д.
Массив
Массивы содержат определенное количество элементов определенного типа. Чтобы компилятор мог зарезервировать требуемое пространство при компиляции программы, вы должны указать тип и количество элементов, которые будет содержать массив, когда он будет определен. Компилятор должен иметь возможность определить это значение при компиляции программы. Как только массив определен, вы используете идентификатор для массива вместе с индексом для доступа к определенным элементам массива. [...] массивы нуль-индексируются; то есть первый элемент находится в индексе 0. Эта схема индексирования указывает на тесную связь в С++ между указателями и массивами и правилами, которые язык определяет для арифметики указателя.
- Справочник по С++ Pocket
Vector
Вектор представляет собой последовательность объектов с динамическим размером, которая обеспечивает произвольный доступ к массиву operator[]
. Функция-член push_back
копирует свои аргументы с помощью конструктора копирования, добавляет, что копия как последний элемент в векторе и увеличивает его размер на единицу. pop_back
делает обратное, удаляя последний элемент. Вставка или удаление элементов с конца вектора берет амортизированное постоянное время, а вставка или удаление из любого другого места занимает линейное время. Это основы векторов. Их гораздо больше. В большинстве случаев вектор должен быть вашим первым выбором в массиве C-стиля. Прежде всего, они имеют динамический размер, что означает, что они могут расти по мере необходимости. Вам не нужно делать всевозможные исследования, чтобы определить оптимальный статический размер, как в случае с массивами C; вектор растет по мере необходимости, и он может быть изменен более или менее вручную, если вам нужно. Во-вторых, векторы предлагают проверку границ с помощью функции-члена at
(но не с operator[]
), так что вы можете что-то сделать, если ссылаетесь на несуществующий индекс, а не просто наблюдаете за сбоем в работе программы или хуже, продолжая выполнение с поврежденными данными.
- С++ Cookbook
Ответы
Ответ 1
массивы:
- - встроенная языковая конструкция;
- почти не изменен с C89;
- обеспечивают только последовательную, индексируемую последовательность элементов; нет звонков и свистов;
- имеют фиксированный размер; вы не можете изменять размер массива в С++ (если только это не массив POD и он выделяется с помощью
malloc
);
- их размер должен быть константой времени компиляции, если они не распределены динамически;
- они берут свое пространство для хранения в зависимости от области, в которой вы их объявляете;
- если динамически распределено, вы должны явно освободить их;
- если они динамически распределены, вы просто получаете указатель, и вы не можете определить их размер; в противном случае вы можете использовать
sizeof
(отсюда общая идиома sizeof(arr)/sizeof(*arr)
, которая, однако, не работает без предупреждения, когда она случайно используется на указателе);
- автоматически распадается на указатели в большинстве ситуаций; в частности, это происходит при передаче их функции, которая обычно требует передачи отдельного параметра для их размера;
- не может быть возвращен из функции;
- нельзя скопировать/назначить напрямую;
- динамические массивы объектов требуют конструктора по умолчанию, поскольку сначала должны быть построены все их элементы;
std::vector
:
- - это шаблонный класс;
- является только конструкцией С++;
- реализуется как динамический массив;
- растет и сжимается динамически;
- автоматически управляет своей памятью, которая освобождается от уничтожения;
- может быть передан/возвращен из функций (по значению);
- может быть скопирован/назначен (это выполняет глубокую копию всех сохраненных элементов);
- не распадается на указатели, но вы можете явно получить указатель на свои данные (
&vec[0]
гарантированно работает как ожидалось);
- всегда сочетает в себе внутренний динамический массив с его размером (количество элементов в настоящее время хранится) и емкость (сколько элементов может быть сохранено в текущем выделенном блоке);
- внутренний динамический массив не выделяется внутри самого объекта (который содержит только несколько полей "бухгалтерии" ), но динамически распределяется распределителем, указанным в соответствующем параметре шаблона; по умолчанию получает память из freestore (так называемая куча), независимо от того, как распределяется фактический объект;
- по этой причине они могут быть менее эффективными, чем "регулярные" массивы для небольших, короткоживущих локальных массивов;
- при перераспределении объекты копируются (перемещаются в С++ 11);
- не требует конструктора по умолчанию для сохраняемых объектов;
- лучше интегрируется с остальной частью так называемого STL (он предоставляет методы
begin()
/end()
, обычный STL typedef
s,...)
Также рассмотрим "современную альтернативу" массивам - std::array
; Я уже описал в еще один ответ разницу между std::vector
и std::array
, вы можете посмотреть на него.
Ответ 2
Я добавлю, что массивы - это очень низкоуровневые конструкции на С++, и вы должны стараться держаться подальше от них как можно больше, когда "изучаете веревки" - даже Бьярне Страуступ рекомендует это (он дизайнер С++),
Векторы очень близки к тем же характеристикам, что и массивы, но с большим количеством удобств и функций безопасности. Вероятно, вы начнете использовать массивы при взаимодействии с API, которые имеют дело с необработанными массивами или при создании собственных коллекций.
Ответ 3
Эта рекомендация в значительной степени ответила на ваш вопрос. Проще говоря, длины векторов являются динамическими, а массивы имеют фиксированный размер.
при использовании массива вы определяете его размер после объявления:
int myArray[100];
myArray[0]=1;
myArray[1]=2;
myArray[2]=3;
для векторов, вы просто объявляете его и добавляете элементы
vector<int> myVector;
myVector.push_back(1);
myVector.push_back(2);
myVector.push_back(3);
...
время от времени вы не будете знать количество необходимых элементов, чтобы вектор был идеальным для такой ситуации.