Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 整数求和蓝色,短+;=短问题_C#_Types_Int_Short - Fatal编程技术网

C# 整数求和蓝色,短+;=短问题

C# 整数求和蓝色,短+;=短问题,c#,types,int,short,C#,Types,Int,Short,C#中的程序: 好的,+=操作符说您将用短时间增加a的值,而=说您将用操作的结果覆盖该值。操作a+b会产生一个int,但不知道它会产生另一个int,而您正试图将该int分配给short。这是因为+=被实现为一个重载函数(其中一个是short,编译器选择最具体的重载)。对于表达式(a+b),编译器在赋值之前默认将结果加宽为int。您必须使用: a = (short)(a + b); 至于赋值和加法赋值行为之间的区别,我想这与此有关(来自msdn) 但是,它有点模糊,因此可能有更深入了解的人可以进

C#中的程序:


好的,
+=
操作符说您将用短时间增加
a
的值,而
=
说您将用操作的结果覆盖该值。操作
a+b
会产生一个int,但不知道它会产生另一个int,而您正试图将该int分配给short。

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

您必须使用:

a = (short)(a + b);
至于赋值和加法赋值行为之间的区别,我想这与此有关(来自msdn)


但是,它有点模糊,因此可能有更深入了解的人可以进行注释。

之所以会出现这种情况,是因为int是定义了
+
的最小有符号类型。任何较小的值都将首先提升为int。
+=
运算符是针对
+
定义的,但有一个特殊的案例规则用于处理不符合目标的结果。

这里有两个问题。第一个问题是“为什么短加短会导致int?”

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

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应该是非法的
  • 那么为什么这是合法的呢
这个问题有一个不正确的前提;上面的第三行是错误的。第7.17.2节规定了C#规范

否则,如果选择的运算符为 预定义的运算符,如果返回 所选运算符的类型为 显式转换为 x、 如果y是隐式可转换的 对于类型为x或运算符为 移位运算符,则操作为 计算为x=(T)(x op y),其中T 是x的类型,但x是 只评估一次

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

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

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

第一个失败是因为规范中定义的short+short=int,就像byte+byte=int一样,但是我希望第二个也会失败,所以我期待在这里看到原因。你找到原因了吗?Eric Lippert在下面尽可能详细地回答了这个问题,所以我不确定你在这里问什么。简言之,是因为
a+=b
a=(短)(a+b)
可能重复,那么增值与增值之间有什么区别呢?我真的没有想到这一点。我以为
+=
只是个速记@jak我理解为
=
操作符分配了一个新值(在这种情况下是错误的类型),但是
+=
使用了不同的实现(即,它按照我们期望的那样添加)。我还一直认为a+=b只是a=a+b的缩写,所以我真的很想在这里看到一个被完全说服的确认。@yvind Brå那么它似乎是这样的:
a+=b
=
a=a+b
,除非+=运算符重载,而且它似乎是用于type
short
,而
short
没有
+
shortA+shortB
变宽并成为
(int)shortA+(int)shortB
。重载运算符只能使用类、结构等用户定义的运算符实现。但它是一个内置的+算术运算符,+=运算符不能直接重载,但用户定义的类型可以重载+运算符,有关详细信息,请访问链接,jak是正确的。+=运算符不是C#中的重载函数。@jak:你用两组括号都试过了吗?您的评论中的代码不同。MSDN上哪里有这样的说明?如果+是预定义的运算符,那么这是错误的,在本例中,显然是这样。在这种情况下,它等于规定的x=(T)(x+y)。如果您能将该页面的链接发送给我,我将提请文档管理员注意。@Eric:当然,它在该页面上:这个答案不正确。+=不是为每个数字类型定义的。参见C#规范第7.17.2节。您的第一个样品不好。如果将
short
替换为
int
一切正常,但如果我们输入更大的数字(使总和大于2^31),将导致int溢出。我的问题是为什么
short+short=int
(对于
byte
)和
int+int=int
(例如不长)。@LBushkin:这真的“同样可能”吗?我以编写编译器为生,每天都要编译超过2^15种类型的程序。如果我把一堆不同程序集中的类型数加在一起,我很容易就会溢出一个短程序集。在编译器空间中,我从来没有遇到过可以合理地使int溢出的问题。编译器在执行包含20亿类型的程序的算术之前,很久就会耗尽虚拟内存。在大多数情况下不太可能出现32位溢出。@Eric:int用于许多计算上下文,其中一些上下文与内存/进程空间无关。作为com
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).
short[] prices = { 10000, 15000, 11000 };
short average = (prices[0] + prices[1] + prices[2]) / 3;