-4

为什么在运行此 C# 代码时会出现除以零异常?对于任何其他值,它返回 3*x。

int x = -2;
x += x++ + ++x % x-- + --x;
4

4 回答 4

13

你得到那个例外是因为你评估0 % 0. 表达式计算如下:

  1. x++计算结果为 -2,x 为 -1。

  2. ++x % x--评估0 % 0将引发异常的哪个(计算需要除以的余数,并且不能除以零)。

要查看结果为何3*x适用于有效值,请考虑此表,其中x最初具有值A

x | 表达 | 价值 | x 之后
=======+==============================+============ ==========+=========
 一个 | x++ | 一个 | 一个 + 1
-------+----------------+------------- ----------+---------
 A + 1 | ++x % x-- | (A + 2) % (A + 2) = 0 | 一个 + 1
-------+----------------+------------- ----------+---------
 A + 1 | --x | 一个 | 一个
-------+----------------+------------- ----------+---------
 一个 | x++ + ++x % x-- + --x | A + 0 + A = 2*A | 一个
-------+----------------+------------- ----------+---------
 一个 | x += x++ + ++x % x-- + --x | A + 2*A = 3*A | 3*A
-------+----------------+------------- ----------+---------

在第二行中,您可以看到分母是0何时A = -2导致异常。

于 2013-10-28T14:43:24.690 回答
7

鉴于 C# 用于评估表达式的规则,您可以像这样重写代码:

int x = -2;
int a = x++;
int b = ++x;
int c = x--;
int d = --x;
x += a + b % c + d;

在这里, 和 的bc0。并且因为%具有比 更高的优先级+,所以首先评估该操作。所以,这就变成了:

x+= a + (0 % 0) + d;

这就是为什么你得到例外。

于 2013-10-28T14:50:25.610 回答
0

你的方程式:

x += x++ + ++x % x-- + --x;

等于

x += ((x++) + (++x)) 
         % 
     ((x--) + (--x));

由于%具有比您的等式更高的优先级,例如:+

x += x++ + (++x % x--) + --x;

现在评估右手边:

    x++ + (++x % x--) + --x;
    //^^^
    //First evaluation x returns -2 but gets modified to -1;

由于一元运算符 (++, --) 具有更高的优先级,它将评估第一个x++返回的位置,-2但将修改为-1下次使用时可用的位置。

现在是第二部分:

    (++x % x--)
    //^^^
    //X returns 0 and modifies to 0

第一部分具有++xwhich return 修改x (以前持有-10并返回0,下一部分是x--它修改x-1但返回0,因为它是一个后减量运算符。

所以你最终得到

0 % 0

因此例外。

于 2013-10-28T15:11:01.107 回答
0

你的方程相当于:

x = 2*x + ((2*x+2) % (x+2));

对于x >= 0,这等于3*x。对于x < 0,它没有。

对于x = -2,其中的一部分尝试被求值:-2 % 0,它抛出 a DivideByZeroException(这提到rem对应于模运算符的 MSIL 指令%可以抛出这个异常)。这样做是因为模 0 是未定义的,就像除以零一样。定义模的一种方法是除法后的余数。由于除以零后无法计算余数,因为除以零是未定义的,所以模 0 也是未定义的。

于 2013-10-28T15:01:13.183 回答