В чем разница между X = X++; vs X++;?
вы когда-нибудь пробовали это раньше?
static void Main(string[] args)
{
int x = 10;
x = x++;
Console.WriteLine(x);
}
выход: 10.
но
static void Main(string[] args)
{
int x = 10;
x++;
Console.WriteLine(x);
}
выход: 11.
может кто-нибудь объяснить, почему это?
16 ответов:
X++ увеличит значение, но затем вернет его старое значение.
таким образом:
static void Main(string[] args) { int x = 10; x = x++; Console.WriteLine(x); }У вас есть X в 11 только на мгновение, а затем он возвращается к 10, потому что 10-это возвращаемое значение (x++).
вы могли бы вместо этого сделать это для того же результата:
static int plusplus(ref int x) { int xOld = x; x++; return xOld; } static void Main(string[] args) { int x = 10; x = plusplus(x); Console.WriteLine(x); }также стоит отметить, что вы бы ожидали результат 11, если бы вы сделали:
static void Main(string[] args) { int x = 10; x = ++x; Console.WriteLine(x); }
в задание
x = x++вы первый извлеките старое значениеxчтобы использовать при вычислении выражения правой части, в этом случае 'x'; затем вы увеличиваетеxк 1. Наконец, вы присваиваете результаты вычисления выражения (10)xчерез оператор присваивания.возможно, эквивалентный код сделает затруднительное положение ясным:
var tmp = x; x++; x = tmp;это эквивалент вашего
x = x++код на C#.
поведение x++ состоит в том, чтобы увеличить x, но вернуть значение до инкремент. Его называют приращением поста по этой причине.
Итак x = x++; проще говоря будет
1. возвращает значение, потом
2. приращение x, потом
3. присвойте исходное значение (возвращенное на шаге 1) x К x.
x++;делает следующее:
int returnValue = x; x = x+1; return returnValue;Как вы можете видеть, исходное значение сохраняется, X увеличивается, а затем возвращается исходное значение.
в конечном итоге это приводит к сохранению значения 10 где-то, установке x равным 11, а затем возвращению 10, что приводит к тому, что x возвращается к 10. Обратите внимание, что x действительно становится 11 за несколько циклов (при условии отсутствия оптимизации компилятора).
Это не ответ на вопрос напрямую, но почему в мире кто-то будет использовать
x = x++;?
Это совершенно противоречит цели постфиксный/префиксный инкремент оператор.
вы можете думать об этом так:
int x = 10;X является контейнером и содержит значение 10.
x = x++;Это можно разбить на:
1) increment the value contained in x now x contains 11 2) return the value that was contained in x before it was incremented that is 10 3) assign that value to x now, x contains 10теперь выведите значение, содержащееся в x
Console.WriteLine(x);и, что неудивительно, он печатает 10.
по определению, x++, возвращает значение x, а затем увеличивает x.
http://blogs.msdn.com/lucabol/archive/2004/08/31/223580.aspx
первое, что вы делаете, называется "пост-инкремент", что означает, что
int x = 10; x++; //x still is 10 Console.WriteLine(x); //x is now 11(post increment)поэтому в тот момент, когда вы назначаете x = x++; x все еще 10, что вы могли бы сделать, если вам нужно x быть 11 в этой строке напишите ++x (думаю, что его называют pre increment исправить меня, если я ошибаюсь) ... в качестве альтернативы правая X++; и чем Х = Х++;
вопрос, это зависит от строки или от оператора означает, что он будет увеличиваться после ; ?
установка оператора инкремента после переменной означает, что инкремент и присвоение происходит после выражение вычисляется... так Первоначальное заявление x = x++; переводится на 1. Оценить x и сохранить значение в памяти tyransient ... Теперь выполните код, вызванный оператором++.... (шаги 2 и 3) 2. Значение приращения x (в переходной памяти) 3. Присвоить увеличенное значение месту хранения x ... Теперь продолжайте выполнение остальной части строки, слева, есть знак=... 5. Поэтому назначьте значение, сохраненное на Шаге 1 (неинкрементированное значение), выражению слева от знака=... что Х
может быть, я не прав, но мне легче понять результат на подобном примере:
public static void main(String[] args) { int x = 10; int y = 0; y = x + x++; //1, 2, 3, 4 x += x; //5 System.out.println("x = " + x + "; y = " + y); //6 }давайте рассмотрим операцию y = x + x++ шаг за шагом:
- компьютер принимает значение X и добавить его к значению x (10 + 10 = 20)
- компьютер помещает результат во временную переменную (temp = 20)
- копьютер увеличивает x (10 + 1 = 11)
- компьютер назначает RUSULT операции правой стороны Хранится в temp переменной y (20)
- компьютер принимает значение X и добавить его к значению x (11 + 11 = 22)
- конечный результат: x = 22; y = 20
а теперь вернемся к нашему примеру и сделаем те же шаги:
public static void main(String[] args) { int x = 10; x = x++; //1, 2, 3, 4 System.out.println(x); //5 }
- компьютер принимает значение x (10)
- компьютер помещает результат во временную переменную (temp = 10)
- копьютер увеличивает x (10 + 1 = 11)
- в компьютер присваивает rusult правой части операции, хранящейся в temp переменной x (10)
- конечный результат: x = 10
Я знаю, что есть много ответов, и принятый один, но я все равно положу свои два цента за еще одну точку зрения.
Я знаю, что этот вопрос был C#, но я предполагаю, что для чего-то вроде постфиксного оператора он не имеет другого поведения, чем C:
int main(){ int x = 0; while (x<1) x = x++; }сборка (да, я отредактировал ее, чтобы сделать ее более читаемой), сгенерированная компилятором, показывает
... mov -8(rbp), 0 ; x = 0 L1: cmp -8(rbp), 1 ; if x >= 1, jge L2 ; leave the loop mov eax, -8(rbp) ; t1 = x mov ecx, eax ; t2 = t1 add ecx, 1 ; t2 = t2 + 1 mov -8(rbp), ecx ; x = t2 (so x = x + 1 !) mov -8(rbp), eax ; x = t1 (kidding, it's the original value again) jmp L1 L2: ...аналогично, цикл делает что-то например:
t = x x = x + 1 x = tбоковое Примечание: включение любых оптимизаций дает вам такой результат сборки:
... L1: jmp L1 ...он даже не потрудился сохранить значение, которое вы сказали ему дать x!
как отдельное заявление,
x++;- это как приращение, так и присвоение. Кажется, что есть некоторые путаницы относительно того, что происходит, когда. Если у нас естьint x = 10; int y = (x++) + 2;мы получим
x = 11иy = 12. Текущее значение x присваивается, и затем происходит приращение и переназначение x.так, при использовании одной и той же переменнойint x = 10; // Create a variable x, and assign an initial value of 10. x = x++; // First, assign the current value of x to x. (x = x) // Second, increment x by one. (x++ - first part) // Third, assign the new value of x to x. (x++ - second part)как ни посмотри, новое значение x равно 11.
Я был совершенно неправ на этот раз.
простое объяснение:
x++ - это постфиксное приращение.
Что делает компилятор:
a) присвоить значение x x b) увеличьте временное значение x (я думаю, оно может быть даже оптимизировано) c) выбросить временное значение x
Если вы хотите, чтобы код возвращал 11 с заданием, напишите:
x = ++x;
результат задание
x = x++;не определено в C и c++
, и я бы предположил то же самое с C# тоже.таким образом, фактическая последовательность операций, которая происходит, зависит от того, как компилятор решает ее реализовать, нет никакой гарантии, произойдет ли сначала назначение или приращение. (это хорошо определено в C#, как указал Джон Скит в комментариях. Хотя теперь я чувствую, что этот ответ имеет гораздо меньшую ценность, я сохраняю этот пост отменен для вопроса ОП и его ответа в комментариях.)
однако, в этом случае, кажется, что последовательность операций, которые происходят:
- старое значение (10) x сохраняется
- x увеличивается для части++
- старое значение теперь присваивается x для присвоения
таким образом, хотя приращение происходит, оно обгоняется назначением со старым значением, таким образом сохраняя x на 10.
HTH
Comments