На этом шаге мы рассмотрим представление векторов в виде массивов.
В спецификации стандартной библиотеки C++ не сказано, что элементы вектора должны храниться в непрерывном блоке памяти. Тем не менее подразумевалось, что такая реализация гарантирована, а соответствующие изменения будут внесены в спецификацию. Следовательно, для любого действительного индекса i в векторе v заведомо истинно следующее условие:
&v[i] == &v[0] + i
Из гарантированного выполнения этого условия следует один важный факт: вектор может задействоваться во всех случаях, когда в программе используется динамический массив. Например, в векторе можно хранить данные обычных строк С типа char* или const char*:
std::vector<char> v; // Создание вектора как // динамического массива типа char v.resize(41); // Выделить память для 41 символа (включая \0) strcpy(&v[0],"hello, world"); // Копирование строки С в вектор printf("%s\n", &v[0]); // Вывод содержимого вектора в виде строки С
Конечно, при таком использовании вектора необходима осторожность (впрочем, при работе с динамическими массивами она необходима всегда). Например, вы должны следить за тем, чтобы размер вектора был достаточным для хранения всех копируемых данных, а если содержимое вектора потребуется как строка С, оно должно завершаться элементом \0. Однако приведенный пример показывает, что когда в программе необходим массив типа Т (например, для существующей библиотеки С), вы можете использовать вектор vector[T] и передать адрес первого элемента.
Обратите внимание: передавать итератор вместо адреса первого элемента было бы неправильно. Тип векторного итератора определяется реализацией; вполне возможно, что он не имеет ничего общего с обычным указателем:
printf("%s\n", v.begin()); // ОШИБКА (может работать, // но нарушает переносимость) pintf("%s\n", &v[0]); // OK
На следующем шаге мы рассмотрим обработку исключений.