关于c#:整数加总蓝调,短+ =短问题

Integer summing blues, short += short problem

C语言程序:

1
2
3
4
5
6
7
8
9
10
short a, b;
a = 10;
b = 10;
a = a + b; // Error : Cannot implicitly convert type 'int' to 'short'.

// we can also write this code by using Arithmetic Assignment Operator as given below

a += b; // But this is running successfully, why?

Console.Write(a);


这里有两个问题。第一个问题是"为什么短加短的结果是int?"

好吧,假设short加short是short,看看会发生什么:

1
2
short[] prices = { 10000, 15000, 11000 };
short average = (prices[0] + prices[1] + prices[2]) / 3;

当然,如果计算是在短时间内完成的话,平均值是-9845。和大于最大可能的短,所以它绕到负数,然后除以负数。

在一个整数算术包围的世界里,用int来做所有的计算更为明智,int是一种类型,它可能有足够的范围使典型的计算不会溢出。

第二个问题是:

  • short加short为int
  • 将int赋给short是非法的
  • A+=B与A=A+B相同
  • 因此short+=short应该是非法的
  • 为什么这是合法的?

这个问题的前提不正确;上面第三行是错误的。C规范在第7.17.2节中规定

Otherwise, if the selected operator is
a predefined operator, if the return
type of the selected operator is
explicitly convertible to the type of
x, and if y is implicitly convertible
to the type of x or the operator is a
shift operator, then the operation is
evaluated as x = (T)(x op y), where T
is the type of x, except that x is
evaluated only once.

编译器将代表您插入强制转换。正确的推理是:

  • short加short为int
  • 将int赋给short是非法的
  • s1+=s2与s1=(短)(s1+s2)相同
  • 因此这应该是合法的

如果它没有为您插入强制转换,那么就不可能在许多类型上使用复合赋值。


好吧,+=操作符说你会用一个短的时间增加a的值,而=操作符说你会用一个操作的结果覆盖这个值。操作a + b生成一个int,不知道它可以做其他操作,而您正试图将该int分配给一个short。


你必须使用:

1
a = (short)(a + b);

至于分配行为和附加分配行为之间的区别,我认为这与此有关(来自msdn)

1
2
3
4
5
6
x+=y
is equivalent to
x = x + y
except that x is only evaluated once. The meaning of the + operator is
dependent on the types of x and y (addition for numeric operands,
concatenation for string operands, and so forth).

然而,它有点含糊,所以马鞭有一个更深的理解可以评论。


这是因为int是定义+的最小有符号类型。任何较小的值都首先被提升为int。+=运算符是针对+定义的,但具有处理不符合目标的结果的特殊情况规则。


这是因为+=是作为重载函数实现的(其中一个是short,编译器选择最具体的重载)。对于表达式(a+b),编译器在赋值之前默认地将结果扩展到int。