C# 增量后问题

C# 增量后问题,c#,C#,我有这个密码 static void Main(string[] args) { int x = 20; int y = 35; x = y++ + x++; y = ++y + ++x; Console.WriteLine(x); Console.WriteLine(y); Console.ReadLine(); } 我希望输出是x=57和y=94。然而,当我被处决时,我得到了56分和93分。 由于某种原因,第3行中没有执行增量后运算符

我有这个密码

static void Main(string[] args)
{
    int x = 20;
    int y = 35;
    x = y++ + x++;
    y = ++y + ++x;
    Console.WriteLine(x);
    Console.WriteLine(y);
    Console.ReadLine();
}
我希望输出是x=57和y=94。然而,当我被处决时,我得到了56分和93分。 由于某种原因,第3行中没有执行增量后运算符

这是因为我们将第3行中表达式的结果赋值给x本身吗?是否存在任何其他情况下,增量后运算符不会产生预期结果


谢谢。

执行顺序由运算符优先级和关联性决定

赋值是右关联的,所以

x = y + x++; 
可以重写

t = y + x++;
x = t;
对于
+
发生在
=
之前这一事实,我找不到一个非常明确的说法
但Ecma文件§14.2中的文本暗示,副作用发生在评估
i++
本身时。在
F(i)+G(i++)*H(i)
中,
H(i)
用新值
i
调用,C中的规则非常简单。它们是:

int x = 20;
int y = 35;
// x = y++ + x++; this is equivalent of
tmp = 35 + 20; y++; x++; x = tmp;
// so here we have x = 55; y = 36
// y = ++y + ++x;
y ++; // 37
x ++; // 56;
y = x + y;
// so here we have y = 93, x = 56;
  • 表达式的子表达式按从左到右、句点、故事结尾进行求值
  • 增量运算符的副作用发生在对该运算符求值时
所以在你的情况下,它会像这样分解;我将假装我们是用C而不是C来做这件事,这样地址和解引用的位置就更清楚了

x = y++ + x++; 
计算x的地址并存储该地址

t1 = &x;
计算y的地址

t2 = &y;
计算存储在刚计算的地址中的值。那是35

t3 = *t2; // 35
刚刚计算的值是表达式的值;它是增量之前的值

再加上一个

t4 = t3 + 1; // 36
在地址中存储36。y现在36岁了

*t2 = t4; // y = 36
y = ++y + ++x; 
现在对x++执行同样的操作:

t5 = &x;
t6 = *t5;     // 20
t7 = t6 + 1;  // 21
*t5 = t7;     // x = 21
好的,现在我们要做加法:

t8 = t3 + t6; // 35 + 20 = 55
并将其分配给首先计算的地址:

*t1 = t8;  // x = 55;
在这句话的结尾,x有三个值。20、21和55。y有两个值,35和36。x现在55岁,y现在36岁

*t2 = t4; // y = 36
y = ++y + ++x; 
现在我们再次做同样的事情,除了这次我们使用增量后的值。跟进:

t1 = &y;
t2 = &y;
t3 = *t2; // 36
t4 = t3 + 1; // 37
*t2 = t4; // y = 37;
t5 = &x;
t6 = *t5; // 55
t7 = t6 + 1; // 56;
*t5 = t7; // x = 56;
t8 = t4 + t7; // 93
*t1 = t8; // y = 93;
所以在这句话的结尾,y有三个值:36,37和93。x有两个值:55和56。y现在是93,x现在是56

我希望输出是x=57和y=94

你为什么会这么想?您的期望与C#规范相反;我很想知道你为什么期望错误的结果。您希望如何生成此代码?你是否期望在任务完成后增加工资?他们为什么要这样做?增量是在计算增量运算符的值时发生的,显然,这必须发生在加法之前,而加法显然必须发生在赋值之前。因此,增量不能在赋值之后发生

由于某种原因,第3行中没有执行增量后运算符


你究竟是怎么得出这个结论的?我向你保证它肯定正在被执行。如果您不相信我,请在调试器中逐步执行。

只是一个提示:如果您将每个测试用例放在一个单独的函数中,这样的场景更容易理解。由于第一次赋值的原因,验证第二次赋值中发生的情况是不必要的困难。但是请注意,求值顺序不必强制执行特定的执行顺序。@Freed是正确的。运算符的执行顺序由优先级和关联性决定。子表达式的求值顺序总是从左到右。我还注意到,如果“x”是一个有副作用的表达式,那么你关于赋值的说法是不正确的。例如:M().x=y+N().x++与t=y+N().x++不同;M().x=t;因为这颠倒了M和N的调用顺序。@Eric,对,但是x显然是问题中的一个变量。我不想说得太多。谢谢你的详细回复。。我们对增量后的理解是错误的。x=y+++x++;对我们来说,意味着x=y+x;y=y+1;x=x+1;这样我们就到了20+35,;35 + 1; 55 + 1; 因为最后一个表达式在x上,我们假设它是56。