short s1=1;s1=s1+1;为什么是错的.而s1+=1;为什么不报错

yishide_weixiao 2012-01-23 10:03:58
如题
...全文
1740 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
小小莫者 2014-03-08
  • 打赏
  • 举报
回复
原来如此。。。感谢各位大虾的指点。。
  • 打赏
  • 举报
回复
P哥在玩MOV指令吧
yishide_weixiao 2012-01-24
  • 打赏
  • 举报
回复 1
那为什么s1+=1;就没有事呢?
余山水 2012-01-24
  • 打赏
  • 举报
回复
short s = (short)0;
s = (short)(s + 1);
需要从类型int转换为short.
  • 打赏
  • 举报
回复 1
c#编译器没有那么高智能,它根据右边的表达式的类型来推断计算的基本类型,而不是根据左边的变量的类型。

看到
s1= s1+1;
的时候编译器就会按照普通的表达式中的数值转换规则,以为你要写代码
s1= s1+(short)1;
,但是c#根本没有定义任何将int转换为short的方法。

而看到
s1+= 1;
编译器就会按照普通的直接操作寄存器的规则,理解为你要写
寄存器<-s1; 寄存器 Add 1; s1<-寄存器(仅int16部分);
。这个“<-”无法翻译为c#语法,它是.net在int上将对数据进行处理的功能,不是c#的而是.net的功能。不经过c#编译器的数值转换检查。

快乐乔巴 2012-01-24
  • 打赏
  • 举报
回复
C# s+=1 为什么会自动强制转换呢
理由(个人理解。。自己也是瞎猜的)

本身+=就是s=s+1的简写 s=s+1要显示转换 那就外面写个括号 s=(short)(s+1) 一看就知道是s+1被转换成short类型了
可是s+=1已经是简写了 我想显示转换这个(short)应该放那个位置呢 s+=(short)1 这明显是对1显示转换了。。。肯定不对 那 s(short)+=1 擦 怎么看也不对啊
所以。。 C#就内部自动帮你转换了(擦 不知道哥这理解对不对 太会YY了
哈哈 不对的地方请牛人指正哈。。。

自动转换会存在一些风险 建议使用checked和unchecked
关键去控制 防止数据丢失
快乐乔巴 2012-01-24
  • 打赏
  • 举报
回复
1. short s1=1;s1=s1+1;为什么是错的

在进行算法运算的时候,内部CLR的虚拟机只能进行最低32位的运算 也就是int
所以不管你是short+short 还是byte+short 最终都会被提升扩展成Int32 也就是int
也就是说s1+1最后是int型 但左边是s1是short型 2楼caozhy兄打的比喻很好 很明显一桶水倒到一杯水里会造成数据丢失 所以是错的
你必须要显示转换才可以

s1 = (short)(s1 = 1);


2.s1+=1;为什么不报错
关于这个+=我以前也是一直认为和x=x+1是等效的 其实还是有区别的
最好的证据就是看反编译后的代码啦

//Reflector反编译后
short s = 1;
s = (short) (s + 1);

没错 += 运算符最后会自动进行强制转换 所以不会报错 这是c#内部自己定义 你也无需纠缠了 知道就可以了

缪军 2012-01-24
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 submain 的回复:]
错误原因:
"s1 = s1 + 1"中的数字1是整形的,而s1是短整形的,
[/Quote]

不是这个原因,你试试看这段代码就知道了:
short s1 = 1; 
short s2 = 1;
s1 = s1 + s2;


结果如下:

缪军 2012-01-24
  • 打赏
  • 举报
回复
楼主举的例子,MSDN中已经有详细的解释,
请楼主参见以下链接中关于"转换"的章节:
http://msdn.microsoft.com/zh-cn/library/ybs77ex4.aspx
缪军 2012-01-24
  • 打赏
  • 举报
回复
呵呵,楼主这个问题很好,我看可以问倒一片
我来回答:
1.s1=1和s1+=1的等号右侧是常数表达式,这时候,可以int32到int16的隐式转换;
2.另一个规则是:等号右侧的计算表达式默认推定为int32,哪怕是两个int16相加,
它不能够隐式转换为int16,s1=s1+1正好是这种情况
threenewbee 2012-01-23
  • 打赏
  • 举报
回复
假如你下命令,把一杯水倒入一个空桶中,我照着做就可以了。
如果你下令,把一桶水倒入一个杯子里面,我就要警告你,请注意有可能桶里面的水太多,杯子装不下。
SubMain 2012-01-23
  • 打赏
  • 举报
回复
错误原因:
"s1 = s1 + 1"中的数字1是整形的,而s1是短整形的,再由于此项目的警告等级设置的太低导致的错误的发生。

你打开 项目属性 的 生成 标签,里面有个 警告等级 的项目,把它改的大一些就没有这个错误了。

111,083

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧