Страницы

Поиск по вопросам

понедельник, 3 февраля 2020 г.

передача вектора в функцию

#cpp #vector


Функция требует в качестве параметра указатель на массив const int*. Требуется передать
вектор v. 

Эквивалентны ли следующие передачи:
&v[0] и v.begin() ?
    


Ответы

Ответ 1



v.begin() возвращает итератор, это не const int*. &*v.begin(), &v[0] и v.data() - эквивалентны. Использование v.data() предпочтительнее, т.к. оно лучше передает намерение.

Ответ 2



Нет, не эквивалентны, т.к. v.begin() возвращает итератор (т.е. std::vector::iterator) на первый элемент vector, а &v[0] указатель на адрес в памяти, где расположен элемент из vector'а (т.е. int*). Соответственно, интерфейс работы с такими типами различен, но, опять же, никто не запрещает разыменовать итератор (но предварительно следует проверить не указывает ли итератор на на v.end()), а затем взять адрес полученного элемента. А так как vector эмулирует работу стандартного массива C (например, быстрый произвольный доступ к элементам), то все элементы в нем располагаются общим скопом (т.е. располагаются подряд в памяти), поэтому вам подойдет способ передачи &v[0], а перемещение по элементам массива через operator ++ примененный к параметру функции, например. Но в таком случае вам стоит заранее обдумать каким именно образом вы будете учитывать границы массива: Передавать размер массива вторым параметром Использовать какой-нибудь барьерный элемент, который должен находиться в конце вашего массива и никогда не должен присутствовать в вашем массиве кроме как барьерный, непосредственно, а также с которым необходимо будет сравнивать значение текущего элемента на каждом шаге для определения конца массива Пример реализации посредством 1-го пункта: #include void func(const int* parm, const int elemsCount) { for (int itemNumber = 0; itemNumber < elemsCount; ++itemNumber, ++parm) { // ToDo: дейтсвия с *parm } } int main() { std::vector v = {1, 2, 3, 4, 5}; func(&v[0], v.size()); }

Комментариев нет:

Отправить комментарий