В чем разница между 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.



может кто-нибудь объяснить, почему это?

654   16  
c#

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 = ++x

будет равно 11.

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 = 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++ шаг за шагом:

  1. компьютер принимает значение X и добавить его к значению x (10 + 10 = 20)
  2. компьютер помещает результат во временную переменную (temp = 20)
  3. копьютер увеличивает x (10 + 1 = 11)
  4. компьютер назначает RUSULT операции правой стороны Хранится в temp переменной y (20)
  5. компьютер принимает значение X и добавить его к значению x (11 + 11 = 22)
  6. конечный результат: x = 22; y = 20

а теперь вернемся к нашему примеру и сделаем те же шаги:

public static void main(String[] args) {
    int x = 10;
    x = x++; //1, 2, 3, 4
    System.out.println(x);  //5
}
  1. компьютер принимает значение x (10)
  2. компьютер помещает результат во временную переменную (temp = 10)
  3. копьютер увеличивает x (10 + 1 = 11)
  4. в компьютер присваивает rusult правой части операции, хранящейся в temp переменной x (10)
  5. конечный результат: 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#, как указал Джон Скит в комментариях. Хотя теперь я чувствую, что этот ответ имеет гораздо меньшую ценность, я сохраняю этот пост отменен для вопроса ОП и его ответа в комментариях.)

однако, в этом случае, кажется, что последовательность операций, которые происходят:

  1. старое значение (10) x сохраняется
  2. x увеличивается для части++
  3. старое значение теперь присваивается x для присвоения

таким образом, хотя приращение происходит, оно обгоняется назначением со старым значением, таким образом сохраняя x на 10.

HTH

Comments

    Ничего не найдено.