Массивы против векторов: вводные сходства и различия [закрыто]


каковы различия между массивом и вектором в C++? Примером различий могут быть библиотеки, символика, способности и т. д.

массив

массивы содержат определенное количество элементов определенного типа. Чтобы компилятор мог зарезервировать необходимый объем пространства при компиляции программы, необходимо указать тип и количество элементов, которые будут содержаться в массиве при его определении. Компилятор должен иметь возможность определите это значение при компиляции программы. После определения массива вы используете идентификатор массива вместе с индексом для доступа к определенным элементам массива. [...] массивы с нуля индексируется, то есть первый элемент имеет индекс 0. Эта схема индексирования указывает на тесную связь в C++ между указателями и массивами и правилами, которые язык определяет для арифметики указателей.

- C++ В Карман Ссылка

вектор

вектор-это последовательность объектов динамического размера, которая обеспечивает стиль массива operator[] произвольный доступ. Функция-член push_back копирует свои аргументы через конструктор копирования, добавляет, что копию в качестве последнего элемента в векторе и увеличивает его размер на одну. pop_back делает прямо противоположное, удаляя последний элемент. Вставка или удаление элементов из конца вектора занимает амортизированное постоянное время, а вставка или удаление от любого другого места требуется линейное время. Это основы векторов. Есть еще много чего для них. В большинстве случаев, вектор должен быть вашим первым выбором на C-стиля массива. Прежде всего, они имеют динамический размер, что означает, что они могут расти по мере необходимости. Вам не нужно делать всевозможные исследования, чтобы выяснить оптимальный статический размер, как в случае с массивами C; вектор растет по мере необходимости, и его можно изменить вручную, Если вам нужно. Во-вторых, векторы предлагают проверку границ с помощью at функция-член (но не с operator[]), Так что вы можете что-то сделать, если вы ссылаетесь на несуществующий индекс вместо того, чтобы просто наблюдать за сбоем программы или, что еще хуже, продолжать выполнение с поврежденными данными.

- C++ Cookbook

3 88

3 ответа:

массивы:

  • являются встроенной языковой конструкцией;
  • пришли почти без изменений из C89;
  • обеспечить только непрерывную, индексируемую последовательность элементов; без наворотов;
  • имеют фиксированный размер; вы не можете изменить размер массива в C++ (если это не массив POD и он выделен с malloc);
  • их размер должен быть константой времени компиляции, если они не выделены динамически;
  • они занимают свое место для хранения в зависимости от области, где вы их объявляете;
  • если они выделяются динамически, вы должны явно освободить их;
  • если они динамически выделяются, вы просто получаете указатель, и вы не можете определить их размер; в противном случае, вы можете использовать sizeof (отсюда общая идиома sizeof(arr)/sizeof(*arr), что, однако, не удается молча при использовании непреднамеренно на указатель);
  • автоматически распадается на указатели в большинстве ситуации; в частности, это происходит при передаче их в функцию, которая обычно требует передачи отдельного параметра для их размера;
  • не может быть возвращен из функции;
  • не может быть скопирован / назначен непосредственно;
  • динамические массивы объектов требуется конструктор по умолчанию, так как все их элементы должны быть построены в первую очередь;

std::vector:

  • является шаблоном класса;
  • это только C++ строительства;
  • реализуется как динамический массив;
  • растет и сжимается динамически;
  • автоматически управлять своей памятью, которая освобождается при уничтожении;
  • может быть передан/возврат из функции (по значению);
  • может быть скопирован / назначен (это выполняет глубокую копию всех сохраненных элементов);
  • не распадается на указатели, но вы можете явно получить указатель на свои данные (&vec[0] гарантированно работает, как ожидалось);
  • всегда приносит вместе с внутренним динамическим массивом его в размере (сколько элементов в настоящее время хранятся) и емкости (сколько элементов можно хранить в текущем выделенном блоке);
  • внутренний динамический массив не выделяется внутри самого объекта (который содержит только несколько полей "бухгалтерия"), но выделяется динамически распределителем, указанным в соответствующий параметр шаблона; по умолчанию он получает память из freestore (так называемая куча), независимо от того, как выделяется фактический объект;
  • по этой причине, они могут быть менее эффективными, чем "обычные" массивы для мелких, короткоживущих, локальные массивы;
  • при перераспределении объектов скопировал (перемещено, в C++11);
  • не требует конструктора по умолчанию для хранимых объектов;
  • is лучше интегрируется с остальной частью так называемого STL (он обеспечивает begin()/end() методы, обычные STL typedefs,...)

также рассмотрим "современную альтернативу" массивам -std::array, Я уже описал в еще один ответ разницу между std::vector и std::array, вы можете взглянуть на него.

Я добавлю, что массивы - это очень низкоуровневые конструкции в C++, и вы должны стараться держаться от них как можно дальше, когда "изучаете веревки" - даже Бьярне Страуструп рекомендует это (он дизайнер C++).

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

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

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);
...

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