5

如果我们尝试运行这段代码:

int d = 10/0;

我们得到一个编译器错误。所以我们不能除以零。

现在考虑这段代码:

  int d = 10;
  int o = d / 0;

d 可以有任何东西并且将任何东西除以零是不行的

我们没有收到编译器错误。该变量具有我们不能除以零的任何内容。为什么当我们尝试将变量除以零时编译器不会出错?

4

5 回答 5

9

您需要查看 C# 语言规范,第 7.18 章。它谈论常量表达式。我只是总结一下基础知识。

C# 编译器努力尝试在编译时评估表达式。只要操作数都有一个已知的值并且运算符是简单的,那么编译器就可以在编译时计算表达式的值并直接使用结果,而不是在运行时生成代码来评估表达式。这听起来像是一种优化,但并非完全如此,在许多地方都需要常量表达式。就像case语句的值、使用const关键字的声明、枚举声明的值和 [attribute] 的参数一样。

所以没有问题10 / 0,这是一个带有文字值和简单运算符的表达式,因此编译器可以直接计算结果并看到它会触发异常,因此在编译时会抱怨它。

由于变量, 不是d / 0常量表达式。您可能会争辩说,编译器很清楚的值,因为它是在上面的语句中分配的。但它不会这样做,优化此类代码是抖动优化器的工作。dd

于 2013-09-01T11:48:48.380 回答
6

因为你的d变量不是常数。

编译器只做基本的(比方说微不足道的)数学检查。您还不够基本,无法由编译器完成,因为它使用的变量不是const.

于 2013-09-01T11:30:41.837 回答
1

在第一种情况下,您有两个常量,因此编译器在编译时解决了这个问题,从而找到了错误。

在第二种情况下,由于您有一个非const变量(d),编译器不会在编译时解决这个问题,因为它无法确保的值,d因此不会发现错误。这将在运行时进行评估,在那里它会出错。

于 2013-09-01T11:31:52.840 回答
1

首先:

int d=10/0;

将在编译时解决,因为它是恒定的。第二个不会被解析,因为编译器只做语法检查,而不做数学检查。

于 2013-09-01T11:31:53.427 回答
0

c# 编译器只做常量值算术检查,并且可以告诉你不能做10/0. 对于编译器来说,它比你想象的要多得多。

更重要的是:c# 编译器允许:

1.0 / 0 // Infinity

因为:

浮点算术溢出或除以零永远不会引发异常,因为浮点类型基于 IEEE 754,因此具有表示无穷大和 NaN(非数字)的规定。

于 2013-09-01T11:33:50.097 回答