На что указывает v.end ()? - PullRequest
       26

На что указывает v.end ()?

1 голос
/ 06 декабря 2011
for (vector<Student_info>::const_iterator iter = students.begin();
     iter != students.end(); ++iter)
    cout << (*iter).name << endl;

В Accelerated C ++ вышеприведенному коду было сказано выводить все данные, содержащиеся в векторе, но если цикл останавливается, когда iter != students.end() равен students.end(), то как он перейдет к последнему элементу вектора

Ответы [ 5 ]

3 голосов
/ 06 декабря 2011

end() указывает где-то за концом контейнера.По соглашению, последовательности в C ++ имеют форму [begin, end), то есть конец является не частью последовательности.Для массивов и векторов end() указывает на индекс, равный размеру массива (который находится вне массива или вектора).

Это удобно во многих аспектах.Например, для пустой последовательности начало и конец контейнера - это один и тот же элемент.Кроме того, значение, возвращаемое end(), обычно используется как «недопустимый» итератор, поскольку оно не указывает на значимый элемент.

3 голосов
/ 06 декабря 2011

end() возвращает специальное значение, которое означает «итерация закончена, остановка».Обычно это итератор для элемента за концом массива - вам не нужно его обрабатывать, вы должны остановиться, как только достигнете его, и это то, что делает цикл.

3 голосов
/ 06 декабря 2011

Цикл, который вы написали, примерно эквивалентен:

vector<Student_info>::const_iterator iter = students.begin();
while (iter != students.end()) {
    cout << (*iter).name << endl;
    ++iter;
}

Это нормальное расширение цикла for в while эквивалент 1 .Каждый раз в цикле итератор iter увеличивается (с ++iter) для перехода к следующему элементу.Когда будет достигнут конец вектора, iter будет равен students.end() и цикл завершится.

1.За исключением области действия iter остается в теле цикла for.

2 голосов
/ 06 декабря 2011

Если я хорошо понял, что вы спросили, это так, потому что последний элемент вектора фактически находится в позиции v.end () - 1.Поэтому элемент перед v.end () должен прекратить цикл для доступа ко всем элементам.Это ты спросил?

1 голос
/ 06 декабря 2011

На самом деле .end() не возвращает итератор в элемент last , скорее он возвращает итератор в past-the-last-element . Итератор до последнего элемента находится прямо перед ним; то есть, если it указывает на последний элемент, то ++it заставляет it указывать на элемент last-the-last.

Спецификация языка называет его итератор конца года

§24.1 / 5 (C ++ 03) читает,

Так же, как обычный указатель на массив гарантирует, что существует значение указателя, указывающее за последним элементом массива, так и для любого типа итератора есть значение итератора, которое указывает за последним элементом соответствующего контейнера. Эти значения называются прошлыми значениями. Значения итератора i, для которых определено выражение * i, называются разыменованными. Библиотека никогда не предполагает, что значения из конца в конец разыменовываются

Также обратите внимание, что разыменование Итератор конца-конца вызывает неопределенное поведение:

auto it = students.end(); //ok
it->someFunction();       //undefined behavior
(*it).someFunction();     //undefined behavior
...