2013-10-28 79 views

回答

13

由于您评估0 % 0而得到该例外。

  1. x++计算为-2和x是-1:表达式如下评价。

  2. ++x % x--计算结果为0 % 0这将抛出异常(计算余数,你需要划分,你不能除以零)。

明白为什么结果是3*x有效值考虑这个表,其中x初始值为A

 
x  | Expression     | Value     | x after 
=======+============================+=======================+========= 
A  | x++      | A      | A + 1 
-------+----------------------------+-----------------------+--------- 
A + 1 | ++x % x--     | (A + 2) % (A + 2) = 0 | A + 1 
-------+----------------------------+-----------------------+--------- 
A + 1 | --x      | A      | A 
-------+----------------------------+-----------------------+--------- 
A  | x++ + ++x % x-- + --x  | A + 0 + A = 2*A  | A 
-------+----------------------------+-----------------------+--------- 
A  | x += x++ + ++x % x-- + --x | A + 2*A = 3*A   | 3*A 
-------+----------------------------+-----------------------+--------- 

在第二行中,你可以看到,分母是0A = -2这导致例外。

+1

@svick答案完全符合这个问题,并且完全值得所有的回应。 –

+0

@ I.G.Pascual是的,这就是为什么我删除了我的评论:miscalculated :) –

+0

@DavidArno也一样;) –

7

给出的规则C#用来计算表达式,你可以重写你这样的代码:

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

这里,bc值是0。并且由于%+具有更高的优先级,因此首先评估该操作。所以,这成为:

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

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

+1

我喜欢这一个。 –

0

你的公式等同于:

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

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

对于x = -2,这一部分试图进行评估:-2 % 0,这将引发DivideByZeroException(此提到,rem MSIL指令,对应于模运算符%,可以抛出该异常)。它这样做是因为模0不定义就像被零除。定义模数的一种方法是除法后的余数。由于除零之后不能计算余数,因为除零除外,因此模0也未定义。

0

您的公式:

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

不等于到:

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

由于%具有higher precedence+你的方程是像

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 

所述第一部分具有++x返回修改x(以前保持-10并返回0,下一部分是x--它修改x-1但是由于它是一个后减量运算符,所以返回0

所以你最终

0 % 0 

,因此除外。

相关问题