Постфиксный и префиксный инкремент понятие?
Я не понимаю концепцию постфикса и префикса инкремента или декремента. Может ли кто-нибудь дать лучшее объяснение?
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 в должности инкремент. Что логически означает, что X равно значению Y после инкремент операция завершена. в должности смысл после.
или
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++. Вы можете видеть, что оператор postfix действительно действует на свой операнд, но он возвращает старое значение до приращения, поэтому результат выражения x++
значение до инкремента. x
, однако, is увеличивается.
в префикс increment также увеличивает свой операнд, но он дает значение операнда после инкремент:
int& operator ++ (int& n)
{
n = n + 1;
return n;
}
это означает, что выражение ++x
принимает значение x
после инкремент.
легко подумать, что выражение ++x
поэтому эквивалентно assignmnet (x=x+1)
. Однако это не совсем так, потому что an инкремент - это операция, которая может означать разные вещи в разных контекстах. В случае простого примитивного целого числа, действительно ++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
Post increment подразумевает значение i
увеличивается после того, как он был назначен k
. Однако pre increment подразумевает, что значение j увеличивается до того, как оно будет присвоено l
.
то же самое относится к декременту.
из стандарта C99 (C++ должен быть таким же, за исключением странной перегрузки)
6.5.2.4 постфиксные операторы инкремента и декремента
ограничения
1 операнд постфиксного приращения или оператор декремента должны иметь квалифицированный или неквалифицированный real или типа указатель и должен быть модифицируемым именующее выражение.
семантика
2 результат постфиксный++ оператор-это значение операнда. После того, как результат получен, значение операнда увеличивается. (То есть значение 1 к нему добавляется соответствующий тип.) Видеть обсуждение аддитивных операторов и сложные задания для информация об ограничениях, типах и преобразования и последствия операции с указателями. Сторона эффект обновления сохраненного значения операнд должен находиться между предыдущая и следующая последовательности точка.
3 оператор postfix -- аналогичен оператору postfix ++, кроме что значение операнда уменьшается (то есть значение 1 соответствующий тип вычитается от него.)
6.5.3.1 операторы инкремента и декремента префикса
ограничения
1 операнд приращения префикса или оператор декремента должны иметь квалифицированный или неквалифицированный real или типа указатель и должен быть модифицируемым именующее выражение.
семантика
2 Значение операнда префиксный оператор ++ увеличивается. Этот результатом является новое значение операнда после инкрементации. Выражение ++E эквивалентно (E+=1). См. обсуждение аддитивных операторов и составное назначение для информации о ограничения, типы, побочные эффекты и преобразования и последствия операции с указателями.
3 префикс -- оператор аналогичен оператору prefix ++, за исключением значение операнда уменьшенный.
pre инкремент перед значением инкремента ++
например:
(++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++ ;
печатает 92 !! Это связано с тем, что приведенное выше выражение эквивалентно:
operator<<(
operator<<(
operator<<( cout, a++ + a++ ),
"<->"
),
a++ + a++ + a++
)