В теории он вызывается каждый раз, поскольку цикл for:
for(initialization; condition; increment)
body;
расширяется до чего-то вроде
{
initialization;
while(condition)
{
body;
increment;
}
}
(обратите внимание на фигурныефигурные скобки, потому что инициализация уже находится во внутренней области видимости)
На практике , если компилятор понимает, что часть вашего условия инвариантна на протяжении всей продолжительности цикла и itне имеет побочных эффектов , он может быть достаточно умен, чтобы убрать его.Обычно это делается с помощью strlen
и тому подобного (что хорошо известно компилятору) в циклах, где его аргумент не записан.
Однако следует отметить, что это последнее условие не всегда тривиально длядоказать;в общем случае легко, если контейнер является локальным для функции и никогда не передается внешним функциям;если контейнер не является локальным (например, он передается по ссылке - даже если он const
), а тело цикла содержит вызовы других функций, компилятору часто приходится предполагать, что такие функции могут изменить его, блокируя таким образом длинуВычисление.
Выполнение этой оптимизации вручную стоит, если вы знаете, что часть вашего условия «дорогая» для оценки (а такое условие обычно нет, так как обычно сводится к вычитанию указателя, котороепочти наверняка встроен).
Редактировать: , как говорили другие, в общем случае с контейнерами лучше использовать итераторы, но для vector
s это не так важно, потому что случайныедоступ к элементам через operator[]
гарантированно будет O (1);на самом деле с векторами это обычно сумма указателя (векторное основание + индекс) и разыменование против указателя приращение (предшествующий элемент + 1) и разыменование итераторов.Поскольку целевой адрес остается прежним, я не думаю, что вы можете получить что-то от итераторов с точки зрения локальности кэша (и даже если это так, если вы не обходите большие массивы в тесных циклах, вы даже не должны замечать такогонекоторые улучшения).
Для списков и других контейнеров использование итераторов вместо произвольного доступа может быть действительно важным, так как использование произвольного доступа может означать обход каждого списка, при увеличенииитератор - это просто разыменование указателя.