for(int i=0;i<число;i++) или for(int i=0;i<число;++i)
Помнится мне, что в универе наши преподаватели нас всегда учили в циклах счетчик увеличивать через i++, но просматривая многие исходники вижу, что чаще используется ++i. Почему так?? Выще производительность?? Или в чем причина?
06.07.11 18:29: Перенесено из 'C/C++'
Re: for(int i=0;i<число;i++) или for(int i=0;i<число;++i)
Здравствуйте, ZegSoft, Вы писали:
ZS>Собственно, возник вопрос, как правильно писать? ZS>for(int i=0;i<число;i++) или for(int i=0;i<число;++i) ZS>Помнится мне, что в универе наши преподаватели нас всегда учили в циклах счетчик увеличивать через i++, но просматривая многие исходники вижу, что чаще используется ++i. Почему так?? Выще производительность?? Или в чем причина?
Для int'ов разницы по скорости нет. Но вот если i — это итератор, то i++ может работать медленнее, чем ++i из-за того, что в перегруженном i++ создаётся копия старого значения (и компилятор может не догадаться выбросить ненужный код).
Поэтому лучше взять за привычку писать ++i.
Sapienti sat!
Re[2]: for(int i=0;i<число;i++) или for(int i=0;i<число;++i)
для сложных типов даже самый умный компилятор может не суметь провести такую оптимизацию.
Пойнт был в единообразности использования префиксного кремента -- и для простых типов (для которых компилятор может провести оптимизацию), так и для сложных.
Re[2]: for(int i=0;i<число;i++) или for(int i=0;i<число;++i)
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, ZegSoft, Вы писали:
ZS>>Собственно, возник вопрос, как правильно писать? ZS>>for(int i=0;i<число;i++) или for(int i=0;i<число;++i) ZS>>Помнится мне, что в универе наши преподаватели нас всегда учили в циклах счетчик увеличивать через i++, но просматривая многие исходники вижу, что чаще используется ++i. Почему так?? Выще производительность?? Или в чем причина?
C>Для int'ов разницы по скорости нет. Но вот если i — это итератор, то i++ может работать медленнее, чем ++i из-за того, что в перегруженном i++ создаётся копия старого значения (и компилятор может не догадаться выбросить ненужный код).
C>Поэтому лучше взять за привычку писать ++i.
Можно еще писать вот так, чтобы полностью как с итераторами получалось.
for (int i = 0; i != number; ++i) { ... }
И вообще в C++11:
for (int i: boost::irange(0, number)) { ... }
Re[3]: for(int i=0;i<число;i++) или for(int i=0;i<число;++i)
Здравствуйте, Wissenschaftler, Вы писали:
C>>Поэтому лучше взять за привычку писать ++i. W>Не надо использовать допотопные компиляторы.
Бывают достаточно тяжёлые итераторы.
Sapienti sat!
Re: for(int i=0;i<число;i++) или for(int i=0;i<число;++i)
Здравствуйте, ZegSoft, Вы писали:
ZS>Собственно, возник вопрос, как правильно писать?
ZS>for(int i=0;i<число;i++) или for(int i=0;i<число;++i)
ZS>Помнится мне, что в универе наши преподаватели нас всегда учили в циклах счетчик увеличивать через i++, но просматривая многие исходники вижу, что чаще используется ++i. Почему так?? Выще производительность?? Или в чем причина?
Дело тут даже не в производительности, а в том, что постинкремент — семантически более сложная операция — она должна не только изменить значение, переменной, но и создать временный объект, в котором сохранить предыдущее ее значение. Более сложная семантика *в общем случае* более сложна в реализации. Поэтому лучше воспитывать в себе привычку не использовать более сложные выражения там, где без труда можно обойтись более простыми, даже если в каких-то частных случаях компилятор способен оптимизировать избыточную сложность.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[4]: for(int i=0;i<число;i++) или for(int i=0;i<число;++i)
W>>Не надо использовать допотопные компиляторы.
D>для сложных типов даже самый умный компилятор может не суметь провести такую оптимизацию. D>Пойнт был в единообразности использования префиксного кремента -- и для простых типов (для которых компилятор может провести оптимизацию), так и для сложных.
для сложных типов есть for each
Здравствуйте, Wissenschaftler, Вы писали:
W>Здравствуйте, dilmah, Вы писали:
W>>>Не надо использовать допотопные компиляторы.
D>>для сложных типов даже самый умный компилятор может не суметь провести такую оптимизацию. D>>Пойнт был в единообразности использования префиксного кремента -- и для простых типов (для которых компилятор может провести оптимизацию), так и для сложных. W>для сложных типов есть for each
Вы про какой for each ?
И как с помощью for each записать обычный for(int i=0;i<число;++i) ?
Здравствуйте, ZegSoft, Вы писали:
ZS>Собственно, возник вопрос, как правильно писать?
ZS>for(int i=0;i<число;i++) или for(int i=0;i<число;++i)
ZS>Помнится мне, что в универе наши преподаватели нас всегда учили в циклах счетчик увеличивать через i++, но просматривая многие исходники вижу, что чаще используется ++i. Почему так?? Выще производительность?? Или в чем причина?
Сейчас не стоит этим заморачиваться,современные компиляторы сами выберут оптимальный вариант без вашей помощи, и, насколько я знаю, все циклы (do while,for) в итоге разворачиваются в один единственный цикл while на языке ассемблера и есть вероятность того, что саму переменную i компилятор вообще выкинет или заменит каким-либо другим более эффективным выражением.
Re[6]: for(int i=0;i<число;i++) или for(int i=0;i<число;++i)
Здравствуйте, _nn_, Вы писали:
__>Вы про какой for each ?
Про студийный. Начиная с 2005, кажись. __>И как с помощью for each записать обычный for(int i=0;i<число;++i) ?
Никак. Обычному "int i" пофиг i++ или ++i. Не пофиг может быть сложным итераторам, для которых существует for each.
Здравствуйте, Wissenschaftler, Вы писали:
W>Здравствуйте, _nn_, Вы писали:
__>>Вы про какой for each ? W>Про студийный. Начиная с 2005, кажись.
Он хуже чем Boost.Foreach.
1. Не поддерживает неконстантные значения.
2. Менее оптимальный код.
__>>И как с помощью for each записать обычный for(int i=0;i<число;++i) ? W>Никак. Обычному "int i" пофиг i++ или ++i. Не пофиг может быть сложным итераторам, для которых существует for each.
Ну а раз никак, то проще приучить себя писать ++i и не заморачиваться
Здравствуйте, NordSky, Вы писали:
NS>разворачиваются в один единственный цикл while на языке ассемблера
Нету в ассемблерах никакого цикла while. Если уж на то пошло, то аналогом будет if и этот ваш нелюбимый goto
А в том же x86 существует несколько инструкций условного перехода, с помощью которых может организовываться цикл.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re[3]: for(int i=0;i<число;i++) или for(int i=0;i<число;++i)
Здравствуйте, andrey_nado, Вы писали:
_>Здравствуйте, NordSky, Вы писали: NS>>все циклы (do while,for) в итоге разворачиваются в один единственный цикл while на языке ассемблера
_>Разве есть такая инструкция процессора — while? Все циклы реализуются через jmp/jz/jnz и подобные команды.
Поясню,
Я немного ошибся с WHILE , грубо говоря, обычно компиляторы неявно приводят циклы типа FOR и WHILE к циклу DO-WHILE а потом цикл DO-WHILE в инструкции ассемблера. Ради интереса гляньте что выдает ваш компилятор при использовании разных циклов
Re[3]: for(int i=0;i<число;i++) или for(int i=0;i<число;++i)
Здравствуйте, ДимДимыч, Вы писали:
ДД>Здравствуйте, NordSky, Вы писали:
NS>>разворачиваются в один единственный цикл while на языке ассемблера
ДД>Нету в ассемблерах никакого цикла while. Если уж на то пошло, то аналогом будет if и этот ваш нелюбимый goto ДД>А в том же x86 существует несколько инструкций условного перехода, с помощью которых может организовываться цикл.
написано же:
"...разворачиваются в один единственный цикл while на языке ассемблера". Естественно подразумевается его реализация! А цикл не while а do-while
Re[4]: for(int i=0;i<число;i++) или for(int i=0;i<число;++i)
Здравствуйте, ДимДимыч, Вы писали:
ДД>Здравствуйте, NordSky, Вы писали:
NS>>"...разворачиваются в один единственный цикл while на языке ассемблера".
ДД>Не всегда в один единственный. Если, например, начальное значение условия на момент компиляции неизвестно, развернется в такое: ДД>
ДД>if (condition)
ДД> do {
ДД> ...
ДД> } while (condition);
ДД>
Да, в примерно такой код все циклы и разворачиваются, в основе структура цикла do-while + if(для пропуска первой итерации если условие не выполняется).
Re: for(int i=0;i<число;i++) или for(int i=0;i<число;++i)