Я не понимаю понятия постфикса и приращения приращения или уменьшения. Может ли кто-нибудь дать лучшее объяснение?
Пост-инкремент и концепция предварительного инкремента?
Ответ 1
Все четыре ответа пока неверны в том смысле, что они утверждают определенный порядок событий.
Полагая, что "городская легенда" привела многих начинающих (и профессиональных) в заблуждение, то есть к бесконечному потоку вопросов о неопределенном поведении в выражениях.
Так.
Для встроенного префиксного оператора C++,
++x
увеличивает x
и производит (как результат выражения) x
как lvalue, тогда как
x++
увеличивает x
и выдает (как результат выражения) исходное значение x
.
В частности, для x++
нет никакого временного упорядочения, подразумеваемого для приращения и получения исходного значения x
. Компилятор может свободно генерировать машинный код, который выдает исходное значение x
, например, он может присутствовать в каком-либо регистре и который задерживает приращение до конца выражения (следующей точки последовательности).
Люди, которые ошибочно полагают, что приращение должно идти первым, и многие из них часто приходят к выводу о том, что определенные выражения должны иметь четко определенный эффект, когда они на самом деле имеют неопределенное поведение.
Ответ 2
int i, x;
i = 2;
x = ++i;
// now i = 3, x = 3
i = 2;
x = i++;
// now i = 3, x = 2
"Сообщение" означает "после", то есть приращение выполняется после считывания переменной. "Pre" означает раньше - поэтому значение переменной сначала увеличивается, а затем используется в выражении.
Ответ 3
Никто не ответил на вопрос: Почему это понятие запутывает?
В качестве основного специалиста в области компьютерных наук мне потребовалось некоторое время, чтобы понять это из-за способа чтения кода.
Неправильно следующее:
x = y ++
X равно y пост. Что логически показалось бы, что X равно значению Y после, выполняется операция приращения. Опубликовать значение после.
или
x = ++ y
X равно y pre -increment. Что логически показалось бы, что X равно значению Y до, выполняется операция приращения. Pre означает до.
Как это работает, на самом деле наоборот. Эта концепция запутанна, потому что язык вводит в заблуждение. В этом случае мы не можем использовать слова для определения поведения.
x = ++ y фактически считывается, поскольку X равно значению Y после приращения.
x = y ++ фактически считывается, поскольку X равно значению Y до приращения.
Слова pre и post назад относительно семантики английского. Они означают только то, где ++ есть отношение Y. Больше ничего.
Лично, если бы у меня был выбор, я бы переключил значения ++ y и y ++. Это всего лишь пример идиомы, которую я должен был изучить.
Если есть метод этого безумия, я хотел бы знать простым языком.
Спасибо за чтение.
Ответ 4
Разница между приращением постфикса, x++
и приращением префикса, ++x
, находится точно в , как, два оператора оценивают свои операнды. Постерическое приращение концептуально копирует операнд в память, увеличивает исходный операнд и, наконец, дает значение копии. Я думаю, это лучше всего иллюстрируется реализацией оператора в коде:
int operator ++ (int& n) // postfix increment
{
int tmp = n;
n = n + 1;
return tmp;
}
Вышеприведенный код не будет компилироваться, потому что вы не можете переопределять операторы для примитивных типов. Компилятор также не может сказать здесь, что мы определяем постфиксный оператор, а не префикс, но допустим, что это правильный и действительный С++. Вы можете видеть, что постфиксный оператор действительно действует на свой операнд, но он возвращает старое значение до приращения, поэтому результатом выражения x++
является значение до приращения. x
, однако, увеличивается.
Приращение префикса также увеличивает его операнд, но он дает значение операнда после приращения:
int& operator ++ (int& n)
{
n = n + 1;
return n;
}
Это означает, что выражение ++x
оценивается значением x
после приращения.
Легко думать, что выражение ++x
поэтому эквивалентно присваиванию mnet (x=x+1)
. Это не совсем так, потому что приращение - это операция, которая может означать разные вещи в разных контекстах. В случае простого примитивного целого, действительно, ++x
подставляется под (x=x+1)
. Но в случае типа класса, такого как итератор связанного списка, приращение приставки итератора наиболее определенно не означает "добавление одного к объекту".
Ответ 5
Это довольно просто. Оба будут увеличивать значение переменной. Следующие две строки равны:
x++;
++x;
Разница заключается в том, что вы используете значение переменной, которая увеличивается:
x = y++;
x = ++y;
Здесь обе линии увеличивают значение y на единицу. Однако первый присваивает значение y до приращения к x, а второе присваивает значение y после приращения к x.
Таким образом, существует только разница, когда приращение также используется как выражение. Приращения после инкремента после возврата значения. Предварительное приращение увеличивается до.
Ответ 6
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
.
То же самое относится к декременту.
Ответ 7
Сообщение приращение (a++)
Если int b = a++, то это означает
int b = a;
a = a+1;
Здесь мы добавляем 1 к значению. Значение возвращается до увеличения
Например, а = 1; b = a++;
Тогда б = 1 и а = 2
Предварительное увеличение (++a)
Если int b = ++a; тогда это значит
a=a+1;
int b=a ;
Предварительное увеличение: это добавит 1 к основному значению. Значение будет возвращено после увеличения, для a = 1; b = ++a; Тогда b = 2 и a = 2.
Ответ 8
Поскольку теперь у нас есть встроенные фрагменты JavaScript, я мог бы также добавить интерактивный пример увеличения до и после. Это не C++, но концепция остается прежней.
let A = 1;
let B = 1;
console.log('A++ === 2', A++ === 2);
console.log('++B === 2', ++B === 2);
Ответ 9
Постинкрементный (x++) инкремент происходит при следующей инструкции:
Пример пост-увеличения:
static void Main(string[] args)
{
int x = 0;
int y= Method(x++);//x=0
Console.WriteLine(x);// now x=1
Console.WriteLine(y);// but y=0;
}
public static int Method(int x)
{
//when called value of x=0;
return x;//returns 0
}
Приращение Pre_increament (++x) происходит в текущем операторе
Пример предварительного увеличения:
static void Main(string[] args)
{
int x = 0;
int y= Method(++x);//x=1
Console.WriteLine(x);// now also x=1
Console.WriteLine(y);//y is 1
}
public static int Method(int x)
{
//inside x=1;
return x; //returns 1
}
Ответ 10
Из стандарта C99 (С++ должен быть тем же самым, если запретить странную перегрузку)
6.5.2.4 Операторы приращения и уменьшения постфикса
Ограничения
1 Операнд пошагового приращения или декремент должен иметь квалифицированных или неквалифицированных реальных или тип указателя и должен быть модифицируемым именующий.
Семантика
2 Результат postfix ++ оператор - значение операнда. После того как результат будет получен, значение операнда увеличивается. (То есть значение 1 к нему добавляется соответствующий тип.) См. обсуждения аддитивных операторов и составное назначение для информацию об ограничениях, типах и конверсий и эффектов операции над указателями. Сторона эффект обновления сохраненного значения операнд должен происходить между предыдущей и следующей точки последовательности.
3 Постфикс-оператор аналогичен оператору postfix ++, кроме что значение операнда уменьшается (т.е. значение 1 из соответствующий тип вычитается от него).
6.5.3.1 Операторы приращения и уменьшения префиксов
Ограничения
1 Операнд приращения префикса или декремент должен иметь квалифицированных или неквалифицированных реальных или тип указателя и должен быть модифицируемым именующий.
Семантика
2 Значение операнда Оператор prefix ++ увеличивается. результатом является новое значение операнда после инкремента. Выражение ++ E эквивалентно (E + = 1). См. Обсуждения аддитивных операторов и сложное присвоение информации о ограничения, типы, побочные эффекты и конверсий и эффектов операции с указателями.
3 Префикс - оператор аналогичен для оператора prefix ++, за исключением того, что значение операнда убавления.
Ответ 11
Предварительное инкремент до значения приращения ++
например:
(++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
Ответ 12
Вы также должны знать, что поведение операторов postincrement/decment отличается в C/С++ и Java.
Учитывая
int a=1;
в C/С++ выражение
a++ + a++ + a++
оценивается до 3, а в Java - до 6. Угадайте, почему...
Этот пример еще более запутанным:
cout << a++ + a++ + a++ << "<->" << a++ + a++ ;
печатает 9 ↔ 2!! Это связано с тем, что вышеупомянутое выражение эквивалентно:
operator<<(
operator<<(
operator<<( cout, a++ + a++ ),
"<->"
),
a++ + a++ + a++
)