X = X ++之间有什么区别; vs X ++ ;?

时间:2008-10-22 14:34:29

标签: c#

你以前试过这个吗?

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 个答案:

答案 0 :(得分:73)

X ++将增加该值,但随后返回其旧值。

所以在这种情况下:

static void Main(string[] args)
{
    int x = 10;
    x = x++;
    Console.WriteLine(x);
}

你只有11点的X,然后它回到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);
}

答案 1 :(得分:57)

在作业x = x++中,首先提取x的旧值,用于评估右侧表达式,在本例中为“x”;然后,将x递增1.最后,通过赋值语句将表达式求值(10)的结果赋值给x

也许等效的代码会使困境变得清晰:

var tmp = x;
x++;
x = tmp;

这相当于C#中的x = x++代码。

答案 2 :(得分:15)

x ++的行为是增加x,但在增量之前返回值 。由于这个原因,它被称为后增量。

所以x = x ++;简单地说就是

<强> 1。返回值,然后

<强> 2。增量x ,然后

第3。将x的原始值(在步骤1中返回)分配给x

答案 3 :(得分:11)

x = 10
x = ++x 

x最终会等于11。

答案 4 :(得分:7)

x++;

执行以下操作:

int returnValue = x;
x = x+1;
return returnValue;

如您所见,保存原始值,增加x,然后返回原始值。

最终做的是将值保存在某处,设置x等于11,然后返回10,这会导致x被设置回10.注意x实际上在几个周期内变为11(假设没有编译器优化)。

答案 5 :(得分:4)

这不是直接回答问题,但为什么世界上任何人都会使用

x = x++;

它完全违背了后增量/预增量运算符的目的。

答案 6 :(得分:3)

你可以这样想:

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。

答案 7 :(得分:2)

根据定义,x ++返回x的值,然后递增x。

http://blogs.msdn.com/lucabol/archive/2004/08/31/223580.aspx

答案 8 :(得分:1)

你做的第一件事叫做“后增量”,意思是

    int x = 10;
    x++; //x still is 10
    Console.WriteLine(x); //x is now 11(post increment)

所以你分配x = x ++的那一刻; x仍然是10你能做什么,如果你需要x在这一行是11写++ x(想想它的前增量纠正我,如果我错了)...或者右x ++;而且比x = x ++;

问题,它是依赖于行还是声明意味着它会在之后递增; ?

答案 9 :(得分:1)

我知道有很多答案,而且是一个被接受的答案,但我仍然会以另外的观点投入我的两分钱。

我知道这个问题是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的值!

答案 10 :(得分:0)

尝试调用++ x并查看是否有效。

答案 11 :(得分:0)

将增量运算符放在变量之后意味着增量和赋值在 之后表达式被评估...所以 原声明 x = x ++; 翻译成 1.评估x并将值存储在tyransient内存中  ...现在执行由++运算符调用的代码....(步骤2和3) 2. x的增量值(在瞬态存储器中) 3.将增量值分配给x的存储位置   ......现在,继续执行该线的其余部分,在左边,有一个=符号...... 5.所以将步骤1中存储的值(未增加的值)赋值给= sign ...左边的表达式,即x

答案 12 :(得分:0)

也许我不对,但我更容易理解类似例子的结果:

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. 的值
  3. 计算机将结果变为临时变量(temp = 20)
  4. 计算机增量x(10 + 1 = 11)
  5. 计算机将存储在右侧的右侧操作的损失归为变量y(20)
  6. 计算机获取x的值并将其添加到x(11 + 11 = 22)
  7. 的值
  8. 最终结果是:x = 22; y = 20
  9. 现在让我们回到我们的示例并执行相同的步骤:

    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. 计算机将存储在右侧的右侧操作的危险分配给变量x(10)
    5. 最终结果是:x = 10

答案 13 :(得分:-2)

作为独立语句,x++;既是增量又是赋值。似乎对于什么时候发生的事情存在一些混淆。如果我们有

int x = 10;
int y = (x++) + 2;

我们将获得x = 11y = 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。

我完全错了。

答案 14 :(得分:-3)

简单说明:

x ++是后缀增量。

编译器的作用:

a)将x的值赋给x b)增加x的临时值(我猜它甚至可以优化掉) c)丢弃临时值x

如果您希望代码在分配时返回11,请写:

x = ++ x;

答案 15 :(得分:-4)

作业的结果

x = x++;

在C和C ++ 中未定义,我也会猜测C#也是如此。

因此,发生的实际操作顺序取决于编译器如何决定实现它,不能保证分配或增量是否会首先发生。 (这在C#中有很好的定义,正如Jon Skeet在评论中指出的那样。虽然我现在觉得这个答案现在的价值低得多,但我保留这个帖子,因为OP的问题及其答案未被删除。评论。)

但是,在这种情况下,似乎发生的操作顺序是:

  1. 保存x的旧值(10)
  2. x为++部分增加
  3. 现在将旧值分配给x以进行分配
  4. 通过这种方式,虽然增量发生了,但它被旧值赋值所取代,因此将x保持为10.

    HTH