Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 83, средняя оценка - 4.81
limelight
7 / 7 / 0
Регистрация: 17.04.2010
Сообщений: 112
26.04.2010, 17:56     Разница между префиксной и постфиксной формой записи счетчика цикла #1
Здравствуйте!

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

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

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

Разница между i++ и ++i.Си C++
C++ Разница между != и <=
C++ Перегрузка постфиксной и префиксной операции инкремента
C++ Разница между С и С++
программа по переводу из постфиксной формы записи в инфиксную с использованием скобок C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Андрей Xomach
8 / 8 / 0
Регистрация: 22.01.2012
Сообщений: 59
12.08.2014, 14:04     Разница между префиксной и постфиксной формой записи счетчика цикла #21
taras atavin, kazak, не совсем так. Для базовых типов оптимизатор (если он, конечно, у вас включен) i++ преобразует в ++i, где это возможно. Однако, для итераторов это не верно, так что есть люди, которые всегда используют ++i для сохранения целостности кода. Однако мне кажется, что i++ все-таки выглядит приятнее.

немного я опоздал с ответом)

по поводу скорости работы:
i++ в простейшем виде:
tmp = i;
++i;
return tmp;
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
17.08.2014, 06:57     Разница между префиксной и постфиксной формой записи счетчика цикла #22
Цитата Сообщение от Андрей Xomach Посмотреть сообщение
aras atavin, kazak, не совсем так. Для базовых типов оптимизатор (если он, конечно, у вас включен) i++ преобразует в ++i, где это возможно.
И это у Вас считается аргументом за идентичность операторов? Раз приходится заменять один на другой, значит они уже не равны и оптимальней тот, на который меняет оптимизатор. Причём, он ведь может быть как просто выключен, так и может потом возникнуть необходимость в замене типа на не базовый. Кроме того, сама замена отнимает время компиляции и если прогер привык писать ++i, то тем самым оптимизирует уже этот этап.
gru74ik
Модератор
 Аватар для gru74ik
3068 / 1313 / 164
Регистрация: 20.02.2013
Сообщений: 3,741
Записей в блоге: 15
17.08.2014, 12:09     Разница между префиксной и постфиксной формой записи счетчика цикла #23
Цитата Сообщение от QenT Посмотреть сообщение
лучше сделать как по стандарту i++
Страуструп в цикле постоянно использует преинкремент (см. Bjarne Stroustrup - The C++ Programming Language - 2013, Fourth Edition, 9.5 Iteration Statements).
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
19.08.2014, 19:21     Разница между префиксной и постфиксной формой записи счетчика цикла #24
Цитата Сообщение от QenT Посмотреть сообщение
и в цикле лучше сделать как по стандарту i++)
Вот только в стандарте описаны оба оператора.

Добавлено через 5 минут
Цитата Сообщение от QenT Посмотреть сообщение
Сам очень много делал тестов с ними, и обоими руками за то, что бы не использовать префиксы и постфиксы в присваивании, уже через пару дней, после написания кода, можно забыть и самому, что ты хотел, а другие и подавно не догадаются!
А там нечего догадываться, всё легко читается. Как раз i=i+1 заставляет гадать, что хотел ещё прикрутить к этому выражению, так как ни кто не думает в терминах "присвоить переменной i сумму i и 1", а вот "увеличить i на 1" - это как раз вполне нормальная мысль и на c++ переводится как ++i. Заметьте, не "i увеличить", а "увеличить i", то есть действие впереди операнда и чтоб их переставить в i++ нужно дополнительное время, хоть и не заметное. А неуклюжее i=i+1 читается и не вызывает необходимости догадываться только на бейсике и ему подобных языках, где инкремента нет.
gru74ik
Модератор
 Аватар для gru74ik
3068 / 1313 / 164
Регистрация: 20.02.2013
Сообщений: 3,741
Записей в блоге: 15
19.08.2014, 19:35     Разница между префиксной и постфиксной формой записи счетчика цикла #25
Цитата Сообщение от taras atavin Посмотреть сообщение
стандарте описаны оба оператора
Описаны оба, конечно. Вопрос о том, какой именно инкремент (пре- или пост-) лучше (эффективнее, красивее, по фен-шую, по науке, правильнее - подставь свой вариант) в циклах использовать.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
19.08.2014, 19:39     Разница между префиксной и постфиксной формой записи счетчика цикла #26
Префиксный, так как постфиксный именно к нему и оптимизируется.
gru74ik
Модератор
 Аватар для gru74ik
3068 / 1313 / 164
Регистрация: 20.02.2013
Сообщений: 3,741
Записей в блоге: 15
19.08.2014, 19:58     Разница между префиксной и постфиксной формой записи счетчика цикла #27
Цитата Сообщение от taras atavin Посмотреть сообщение
Префиксный, так как постфиксный именно к нему и оптимизируется.
Согласен, я тоже считаю, что префиксный инкремент в циклах соответствует духу Дзен. Но тут есть противники такой позиции
gru74ik
Модератор
 Аватар для gru74ik
3068 / 1313 / 164
Регистрация: 20.02.2013
Сообщений: 3,741
Записей в блоге: 15
19.08.2014, 20:00     Разница между префиксной и постфиксной формой записи счетчика цикла #28
Цитата Сообщение от QenT Посмотреть сообщение
лучше сделать как по стандарту
Согласен. Посмотрим, как же в стандарте в циклах юзают инкремент:
Миниатюры
Разница между префиксной и постфиксной формой записи счетчика цикла   Разница между префиксной и постфиксной формой записи счетчика цикла   Разница между префиксной и постфиксной формой записи счетчика цикла  

gru74ik
Модератор
 Аватар для gru74ik
3068 / 1313 / 164
Регистрация: 20.02.2013
Сообщений: 3,741
Записей в блоге: 15
19.08.2014, 20:05     Разница между префиксной и постфиксной формой записи счетчика цикла #29
Но, в то же время:
Миниатюры
Разница между префиксной и постфиксной формой записи счетчика цикла  
gru74ik
Модератор
 Аватар для gru74ik
3068 / 1313 / 164
Регистрация: 20.02.2013
Сообщений: 3,741
Записей в блоге: 15
19.08.2014, 20:15     Разница между префиксной и постфиксной формой записи счетчика цикла #30
Так что "по стандарту" не получится Там даже внутри циклов оба варианта используются.
Видать, в комитете по стандартизации С++ тоже любители потроллить сидят

Выход, видимо, один - разобраться с пониманием того, что использовать и как, а не слепо копировать стандарт или авторитетов.
_Ivana
2177 / 1382 / 124
Регистрация: 01.03.2013
Сообщений: 4,120
Записей в блоге: 2
19.08.2014, 21:08     Разница между префиксной и постфиксной формой записи счетчика цикла #31
Вот ведь вопрос серьезный, как у остроконечников/тупоконечников Свифта. Если смотреть с точки зрения ассемблерного листинга, то вроде как одна бабка говорит, что префиксная эффективнее. А если забыть про эти копейки и смотреть с точки зрения стройности кода, то разработчики С (а не С++, кстати) вполне правильно сделали, придумав оба варианта, и в примерах кода применяют тот, который нагляднее отражает суть задачи - в последнем скрине пример заполнения массива по индексу, ну коряво бы выглядело начинать с -1 и делать предынкремент, гораздо стройнее смотрится начинать индекс с нуля и делать постинкремент.
ЗЫ а если счетчик еще и беззнаковый, то при предынкременте начинать надо вообще с 255 если он восьмибитный и с других чисел, если другой размер типа. И зачем с этим корячиться, если есть постинкремент?
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
19.08.2014, 21:11     Разница между префиксной и постфиксной формой записи счетчика цикла #32
А какое отношение цикл имеет к стартовому индексу? Этот блок в любом случае выполняется после тела.
_Ivana
2177 / 1382 / 124
Регистрация: 01.03.2013
Сообщений: 4,120
Записей в блоге: 2
19.08.2014, 21:15     Разница между префиксной и постфиксной формой записи счетчика цикла #33
Если это так, тогда это я лохЪ, поскольку не применяю предынкремент по причине моего незнания и вытекающей из него неуверенности Тогда надо вышенаписанное мной считать бредом, а мне учить предынкремент ))))
John Prick
19.08.2014, 22:11
  #34

Не по теме:

Цитата Сообщение от _Ivana Посмотреть сообщение
вышенаписанное мной считать бредом, а мне учить предынкремент
Первое верное, второе - спорно, так как учить надо цикл for.

Jupiter
19.08.2014, 22:23
  #35

Не по теме:

Цитата Сообщение от _Ivana Посмотреть сообщение
ну коряво бы выглядело начинать с -1 и делать предынкремент, гораздо стройнее смотрится начинать индекс с нуля и делать постинкремент.
ЗЫ а если счетчик еще и беззнаковый, то при предынкременте начинать надо вообще с 255 если он восьмибитный и с других чисел, если другой размер типа. И зачем с этим корячиться, если есть постинкремент?
0xFF же, а то и ~0

numizmat
0 / 0 / 0
Регистрация: 18.01.2015
Сообщений: 4
27.06.2015, 04:50     Разница между префиксной и постфиксной формой записи счетчика цикла #36
C++
1
2
3
4
5
6
7
8
  int i1 = 0;
     int i2 = 0;
    
    i2 = ++i1;
           cout << "i1= " << i1 << "  i2= " << i2 << endl;   
    
    i2 = i1++;
        cout << "i1= " << i1 << "  i2= " << i2 << endl;
Получим.
i1= 1 i2= 1

i1= 2 i2= 1
daslex
1084 / 494 / 101
Регистрация: 02.08.2011
Сообщений: 2,408
27.06.2015, 07:38     Разница между префиксной и постфиксной формой записи счетчика цикла #37
Вопрос внимательнее прочти и обрати внимание на дату...
А насчет
Цитата Сообщение от gru74ik Посмотреть сообщение
Так что "по стандарту" не получится Там даже внутри циклов оба варианта используются.
Скотт Мейерс (More Effective c++) писал
The prefix version is always preferred over the postfix in regards to objects, especially in regards to iterators.
Префиксная версия всегда предпочтительнее чем постфиксная в отношении объектов, особенно в отношении итераторов
По стандарту вообще мало что получится, если все уже не знать. Они разбросали важные кусочки по очень разным местам.
Oleg Frias
0 / 0 / 0
Регистрация: 21.02.2016
Сообщений: 2
24.02.2016, 23:15     Разница между префиксной и постфиксной формой записи счетчика цикла #38
опоздал)
TheCalligrapher
С чаем беда...
Эксперт С++
 Аватар для TheCalligrapher
2781 / 1427 / 393
Регистрация: 18.10.2014
Сообщений: 2,620
25.02.2016, 03:27     Разница между префиксной и постфиксной формой записи счетчика цикла #39
Во-первых, у префиксного и постфиксного инкремента разная семантика результата. Первый возвращает новое значение (как lvalue), второй - старое значение (как rvalue). Поэтому в реальном коде следует выбирать именно тот вариант, который возвращает именно нужный вам результат. Это - главный критерий выбора между префиксным и постфиксным вариантами.

В-вторых, когда возвращаемое значение оператора роли не играет вообще (игнорируется), как в вышеприведенном примере с 'for', предпочтительнее применять именно префиксный вариант. В общем случае, префиксный вариант эффективнее, ибо он не требует создания копии объекта с сохраненным старым значением. Именно так, через создание копии со старым значением в общем случае реализуется постфиксный инкремент. Особо умный компилятор может уметь оптимизировать код постфиксного инкремента в ситуациях, когда результат оператора игнорируется, тем самым устраняя разницу в производительности. Но полагаться на это не стоит.

В-третьих, вышесказанные соображения эффективности применимы в первую очередь к относительно "тяжелым" пользовательским типам, и не играют роли при работе с фундаментальными типами, такими как 'int'. Тем не менее, для единообразия в С++ принято придерживаться префиксного инкремента. В языке С, где инкремент применим только к фундаментальным типам, не имеет значения, какой вариант применять (разумеется, только в ситуациях, когда вы игнорируете результат оператора).

В-четвертых, никакого "как в стандарте" тут нет и быть не может. Стандарт такими вопросам не занимается.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.02.2016, 03:54     Разница между префиксной и постфиксной формой записи счетчика цикла
Еще ссылки по теме:

C++ перегрузка постфиксной и префиксной формы оператора ++
C++ ++i и i++ разница при выполнении цикла
C++ Как сделать чтобы в постфиксной записи кроме цифр выводились еще и обычные символы

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

Или воспользуйтесь поиском по форуму:
hoggy
5031 / 2114 / 403
Регистрация: 15.11.2014
Сообщений: 4,799
Завершенные тесты: 1
25.02.2016, 03:54     Разница между префиксной и постфиксной формой записи счетчика цикла #40
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Особо умный компилятор может уметь оптимизировать код постфиксного инкремента в ситуациях, когда результат оператора игнорируется, тем самым устраняя разницу в производительности. Но полагаться на это не стоит.
все топовые компиляторы уже давным давно
научились оптимизировать неиспользуемые значения.
Yandex
Объявления
25.02.2016, 03:54     Разница между префиксной и постфиксной формой записи счетчика цикла
Ответ Создать тему
Опции темы

Текущее время: 13:57. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru