Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 83, средняя оценка - 4.81
limelight
8 / 8 / 3
Регистрация: 17.04.2010
Сообщений: 112
#1

Разница между префиксной и постфиксной формой записи счетчика цикла - C++

26.04.2010, 17:56. Просмотров 13645. Ответов 57
Метки нет (Все метки)

Здравствуйте!

Когда оформлял циклы всегда использовал такую запись:

C++
1
for(int i=0; i<10; i++)
, которая означает что цикл будет выполнен не более 10 раз, счетчик будет увеличен только после выполнения тела цикла и успешного выполнения условия(i<10).

В последнее время стал встречать другую запись:
C++
1
for(int i=0; i<10; ++i)
В чем принципиальное различие этих форм записей для использования цикла?
Когда какой более предпочтителен?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.04.2010, 17:56
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Разница между префиксной и постфиксной формой записи счетчика цикла (C++):

Перегрузка постфиксной и префиксной операции инкремента
Здравствуйте! У меня возник вопрос: почему выводит разный результат, казалось...

Перегрузка постфиксной и префиксной формы оператора ++
доброго времени суток форумчане, у меня такой вопрос, как перегрузить...

Подсчет выражения в постфиксной записи
Как подсчитать значение выражения? #include&lt;iostream&gt; using namespace std;...

Найти ошибку в программе постфиксной записи
В постфиксной записи (или обратной польской записи) операция записывается после...

Странные значения счетчика цикла. ПОМОГИТЕ!
#include &lt;iostream&gt; using namespace std; double unitInterval = 0.2 ;...

Перевод из постфиксной формы записи в инфиксную с использованием скобок
перевод буквенного выражения с проверкой правильности ввода

57
M128K145
Эксперт JavaЭксперт С++
8320 / 3540 / 419
Регистрация: 03.07.2009
Сообщений: 10,708
26.04.2010, 20:34 #2
limelight, применительно к циклам - никакой разницы.
Около месяца назад этот вопрос уже обсуждался. Если я найду эту тему, то скину ссылку
0
MafiaWest
99 / 98 / 32
Регистрация: 24.04.2010
Сообщений: 284
Записей в блоге: 1
26.04.2010, 20:45 #3
Я полностю не уверен,но в 1 записи і будет увеличино после виполнения цикла,а в втором -до виполнения тела цикла

Хотя нет,в циклах оно виполняється одинаково
0
GAME
23 / 23 / 5
Регистрация: 31.10.2009
Сообщений: 199
26.04.2010, 20:48 #4
Цитата Сообщение от MafiaWest Посмотреть сообщение
Я полностю не уверен,но в 1 записи і будет увеличино после виполнения цикла,а в втором -до виполнения тела цикла

+1

Разница только в том, что ты будешь делать в цикле. Например если есть операции с массивами mas[i] , то чаще всего используют i++. А вообще это зависит от содержимого цикла.
0
M128K145
Эксперт JavaЭксперт С++
8320 / 3540 / 419
Регистрация: 03.07.2009
Сообщений: 10,708
26.04.2010, 20:55 #5
GAME, MafiaWest, господа, а если проверить?
http://codepad.org/TIWH0Rdb
0
GAME
23 / 23 / 5
Регистрация: 31.10.2009
Сообщений: 199
26.04.2010, 21:26 #6
M128K145, нас обманули )) жестоко обманули ))
0
kazak
3057 / 2378 / 255
Регистрация: 11.03.2009
Сообщений: 5,438
Завершенные тесты: 1
27.04.2010, 06:01 #7
Просто ++i выполняется быстрее.
0
QenT
39 / 39 / 8
Регистрация: 29.01.2009
Сообщений: 244
27.04.2010, 06:34 #8
http://codepad.org/vIbr51Yi

Если переменая с префиксом или постфиксом используется без присваивания - то это ни как не играет роли!(и в цикле лучше сделать как по стандарту i++)
Если же идет присваивание(пример a = i++) то:
a = i++; // a = i; i = i + 1;
a = ++i; // i = i + 1; a = i;

или

f(i++); // f( i ); i = i + 1;
f(++i); // i = i + 1; f( i );

Сам очень много делал тестов с ними, и обоими руками за то, что бы не использовать префиксы и постфиксы в присваивании, уже через пару дней, после написания кода, можно забыть и самому, что ты хотел, а другие и подавно не догадаются!
1
rangerx
1941 / 1550 / 478
Регистрация: 31.05.2009
Сообщений: 2,913
27.04.2010, 11:33 #9
http://www.cyberforum.ru/cpp-beginners/thread115615.html#post656751
1
taras atavin
4204 / 1763 / 212
Регистрация: 24.11.2009
Сообщений: 27,565
27.04.2010, 11:35 #10
Цитата Сообщение от M128K145 Посмотреть сообщение
limelight, применительно к циклам - никакой разницы.
Разница малозаметна, но есть. И относится именно к циклам: перфиксная форма работает чуть быстрее.
0
Seishin
12 / 12 / 3
Регистрация: 15.04.2010
Сообщений: 31
27.04.2010, 11:44 #11
Что-то только непонятно за счет чего она быстрее работает ((... код то одинаковый

Assembler
1
add         eax,1
0
taras atavin
4204 / 1763 / 212
Регистрация: 24.11.2009
Сообщений: 27,565
27.04.2010, 11:48 #12
В постфиксной форме к этому добавлена возня с параметром и временным объектом-значением.
0
kazak
3057 / 2378 / 255
Регистрация: 11.03.2009
Сообщений: 5,438
Завершенные тесты: 1
27.04.2010, 11:51 #13
Не совсем. В постфиксном варианте создается временный объект, содержащий прежнее значение переменной. За счет этого постфиксный инкремент работает медленее.
0
Seishin
12 / 12 / 3
Регистрация: 15.04.2010
Сообщений: 31
27.04.2010, 12:25 #14
В любом случае инкрементирование и все действия в последней части конструкции if( ; ; (вот эти) ) выполняется только после прохода тела цикла. При этом, если там выполняются какие-нить действия связанные со счетчиком, то при

C++
1
2
3
4
5
6
7
char m[3] = {10, 20, 30};   
char lc = -1;
for( int i = 0; i < 3; lc = m[i], i++ )
{}
 
for( int i = 0; i < 3;  lc = m[i], ++i )
{}
получим на второй итерации lc == 10 в обоих случаях и i == 1...

При
C++
1
2
3
4
5
for( int i = 0; i < 3; i++, lc = m[i] )
{}
 
for( int i = 0; i < 3; ++i, lc = m[i])
{}
получим на второй итерации lc == 20 в обоих случаях и i == 1, тут надо быть осторожным, ибо после последней итерации и до проверки выполнения i<3, i == 3 и m[3] == Хз, т.е. можно залезть за границы массива..

А постфикс и префикс имеют смысл только в случае
C++
1
2
3
4
5
for( int i = 0; i < 3; lc = m[i++] )
{}
 
for( int i = 0; i < 3;  lc = m[++i])
{}
Добавлено через 8 минут
taras atavin,
kazak,
(( может от компилятора зависит

Объясните нубу, в обоих случаях

Assembler
1
2
3
4
5
6
7
8
00411AEE C7 45 E0 00 00 00 00 mov         dword ptr [ebp-20h],0 
00411AF5 EB 09            jmp         00411B00 
00411AF7 8B 45 E0         mov         eax,dword ptr [ebp-20h] 
00411AFA 83 C0 01         add         eax,1 
00411AFD 89 45 E0         mov         dword ptr [ebp-20h],eax 
00411B00 83 7D E0 03      cmp         dword ptr [ebp-20h],3 
00411B04 7D 02            jge         00411B08 
00411B06 EB EF            jmp         00411AF7
1
kazak
3057 / 2378 / 255
Регистрация: 11.03.2009
Сообщений: 5,438
Завершенные тесты: 1
27.04.2010, 14:28 #15
Seishin, спасибо за твою любознательность. Оказывается если инкремент просто применять без всяких присваиваний и использований в качестве индекса, то компилятор не видит разницы между префиксом и постфиксом и генерирует один и тотже код. В том числе и для циклов.
1
Serg046
21 / 21 / 6
Регистрация: 07.01.2010
Сообщений: 376
12.08.2014, 13:32 #16
Цитата Сообщение от kazak Посмотреть сообщение
Оказывается если инкремент просто применять без всяких присваиваний
даже более, если собирать в release, то современный компилятор оптимизирует постфикс, где можно.
0
DrOffset
7518 / 4514 / 1097
Регистрация: 30.01.2014
Сообщений: 7,362
12.08.2014, 13:36 #17
Цитата Сообщение от Seishin Посмотреть сообщение
Объясните нубу, в обоих случаях
Постфикс или префикс может быть критичен для перегруженных соответсвующих операторов у классов (там оптимизацию получится сделать не всегда), например итераторов. Для встроенных типов, компилятор уже давно проводит такую оптимизацию. А пишут так везде просто для единообразия.
1
Serg046
21 / 21 / 6
Регистрация: 07.01.2010
Сообщений: 376
12.08.2014, 13:43 #18
Цитата Сообщение от DrOffset Посмотреть сообщение
А пишут так везде просто для единообразия
выше же указал про release. В рамках модульных тестов к примеру, это может быть важным.
0
SatanaXIII
12.08.2014, 13:47
  #19

Не по теме:

А еще постфиксная форма записи ворует детей, да.

0
Serg046
21 / 21 / 6
Регистрация: 07.01.2010
Сообщений: 376
12.08.2014, 14:04 #20
Цитата Сообщение от krv Посмотреть сообщение
А можно более развернуто про быстрее?
Выше написано.
Цитата Сообщение от taras atavin Посмотреть сообщение
В постфиксной форме к этому добавлена возня с параметром и временным объектом-значением.
0
12.08.2014, 14:04
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.08.2014, 14:04
Привет! Вот еще темы с решениями:

Как сделать чтобы в постфиксной записи кроме цифр выводились еще и обычные символы
Есть код который делает конвертацию например 1 + 2 * 3 --&gt;123*+ но а + b* c...

++i и i++ разница при выполнении цикла
Доброго времени суток! Действительно ли в цикле вида: for(int i = 0; i &lt; n;...

Разница между if else и else if
Привет, у меня возник &quot;нубский&quot; вопрос. Этот код, это же соркащенная версия...

Разница между С и С++
Если не брать во внимание объекты и классы, то разница состоит только лишь в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru