Постфиксный и префиксный инкремент понятие?
Я не понимаю концепцию постфиксного и префиксного инкремента или декремента. Может ли кто - нибудь дать лучшее объяснение?
9 ответов:
все четыре ответа до сих пор являются неправильно, в том, что они утверждают конкретный порядок событий.
полагая, что "городская легенда" привела многих новичков (и профессионалов) в заблуждение, а именно, бесконечный поток вопросов о неопределенном поведении в выражениях.
так.
для встроенного оператора префикса C++,
++x
с шагом
x
и производит как результат выраженияx
как lvalue, в то время какx++
с шагом
x
и выдает в результате выражения исходное значениеx
.в частности, для
x++
нет нет времени на заказ подразумевается для приращения и производства первоначальной стоимостиx
. Компилятор может свободно выдавать машинный код, который создает исходное значениеx
, например, он может присутствовать в некотором регистре, и это задерживает приращение до конца выражения (следующая последовательность точка.)люди, которые неправильно считают, что приращение должно быть первым, и их много, часто делают вывод, что определенные выражения должны иметь хорошо определенный эффект, когда они на самом деле имеют неопределенное поведение.
int i, x; i = 2; x = ++i; // now i = 3, x = 3 i = 2; x = i++; // now i = 3, x = 2
'Post' означает после-то есть, приращение выполняется после чтения переменной. "Pre" означает раньше - поэтому значение переменной сначала увеличивается, а затем используется в выражении.
никто не ответил на вопрос: почему это понятие сбивает с толку?
как магистр компьютерных наук мне потребовалось некоторое время, чтобы понять это из-за Как я читал код.
следующее неверно!
x = y++
X равно y post инкремент. Что логически означает, что X равно значению Y после инкремент операция завершена. Post смысл после.
или
x = ++y
X равно y pre-инкремент. Что логически означает, что X равно значению Y до операция инкремента выполнена. Pre смысл до.
Как это работает на самом деле наоборот. Это понятие сбивает с толку, потому что язык вводит в заблуждение. В этом случае мы нельзя использовать слова для определения поведения.
x=++y фактически читается как X равно значению Y после инкремент.
x=y++ фактически читается как X равно значению Y до инкремент.слова pre и post являются назад относительно семантики английского языка. Они только означают, где ++ находится в отношении Y. больше ничего.
лично, если бы у меня был выбор, я бы переключил значения ++Y и y++. Это просто пример идиомы, которую мне пришлось выучить.
Если есть способ для этого безумия, я хотел бы знать в простых терминах.
Спасибо за чтение.
разницу между постфикс инкремент,
x++
и префикс инкремент,++x
, находится именно в как эти два оператора оценивают свои операнды. Постфиксное приращение концептуально копирует операнд в память, увеличивает исходный операнд и, наконец, дает значение копии. Я думаю, что это лучше всего иллюстрируется реализацией оператора в коде:int operator ++ (int& n) // postfix increment { int tmp = n; n = n + 1; return tmp; }
приведенный выше код не будет компилироваться, потому что вы не можете переопределить операторы для примитивных типов. Компилятор также не может сказать здесь, что мы определяем постфикс оператор, а не префикс, но давайте притворимся, что это правильный и действительный C++. Вы можете видеть, что постфиксный оператор действительно действует на свой операнд, но он возвращает старое значение до приращения, поэтому результат выражения
x++
значение до инкремента.x
, однако, и увеличивается.в префикс increment также увеличивает свой операнд, но он дает значение операнда после инкремент:
int& operator ++ (int& n) { n = n + 1; return n; }
это означает, что выражение
++x
принимает значениеx
после инкремент.легко подумать, что выражение
++x
поэтому эквивалентно assignmnet(x=x+1)
. Это не совсем так, однако, потому что инкремент - это операция, которая может означать разные вещи в разных контекстах. В случае простого примитивного целого числа, действительно++x
- это взаимозаменяемый для(x=x+1)
. Но в случае типа класса, такого как итератор связанного списка, приращение префикса итератора наиболее определенно не означает "добавление одного к объекту".
Это довольно просто. Оба будут увеличивать значение переменной. Следующие две строки равны:
x++; ++x;
разница в том, если вы используете значение переменной увеличивается:
x = y++; x = ++y;
здесь обе строки увеличивают значение y на единицу. Однако первый присваивает значение y перед приращением к x, а второй присваивает значение y после приращения к x.
Так что есть только разница, когда приращение также используется в качестве выражения. Пост-инкремент увеличивается после возврата значения. Предварительное приращение увеличивается раньше.
int i = 1; int j = 1; int k = i++; // post increment int l = ++j; // pre increment std::cout << k; // prints 1 std::cout << l; // prints 2
пост инкремент подразумевает значение
i
увеличивается после того, как он был назначенk
. Однако предварительное приращение подразумевает, что значение j увеличивается до того, как оно будет присвоеноl
.то же самое относится и к декременту.
от стандарта C99 (C++ должен быть таким же, за исключением странной перегрузки)
6.5.2.4 Постфиксные операторы инкремента и декремента
ограничения
1 операнд постфиксного приращения или оператор декремента должен иметь квалифицированный или неквалифицированный реальный или типа указатель и должен быть модифицируемым именующее выражение.
семантика
2 результат постфиксный++ оператор-это значение операнда. После того, как результат получен, значение операнда увеличивается. (То есть значение 1 к нему добавляется соответствующий тип.) Видеть обсуждение аддитивных операторов и сложные задания для информация об ограничениях, типах и переходы и эффекты операции над указателями. Сторона эффект обновления сохраненного значения операнд должен находиться между предыдущая и следующая последовательность точка.
3 постфиксный оператор -- аналогичен к постфиксного++, за исключением что значение операнда уменьшается (то есть значение 1 соответствующий тип вычитается от него.)
6.5.3.1 префиксные операторы инкремента и декремента
ограничения
1 операнд приращения префикса или оператор декремента должен иметь квалифицированный или неквалифицированный реальный или типа указатель и должен быть модифицируемым именующее выражение.
семантика
2 Значение операнда префикс ++ оператор увеличивается на единицу. Этот результатом является новое значение операнда после инкремента. Выражение ++E эквивалентно (E+=1). См. обсуждение аддитивных операторов и составное назначение для информации о ограничения, типы, побочные эффекты и переходы и эффекты операции над указателями.
3 префикс-оператор является аналогом к оператору prefix++, за исключением того, что значение операнда равно уменьшенный.
предварительный шаг, прежде чем инкрементировать значение
++
например:(++v) or 1 + v
пост инкремент после инкремента значение
++
например:(rmv++) or rmv + 1
программа:
int rmv = 10, vivek = 10; cout << "rmv++ = " << rmv++ << endl; // the value is 10 cout << "++vivek = " << ++vivek; // the value is 11
вы также должны знать, что поведение постинкремент операторов/декремента отличается в C/C++ и Java.
дано
int a=1;
в C/C++ выражение
a++ + a++ + a++
оценивает до 3, в то время как в Java он оценивает до 6. Догадаться, почему...
этот пример еще более запутанной:
cout << a++ + a++ + a++ << "<->" << a++ + a++ ;
печатает 9 2 !! Это потому, что приведенное выше выражение эквивалентно:
operator<<( operator<<( operator<<( cout, a++ + a++ ), "<->" ), a++ + a++ + a++ )