欢迎光临 Rick 's BLOG
日志首页  | C# .Net编程  | 原创作品  | 生活点滴  | C\C++相关  | 多媒体相关※ERMP  | VB相关  | 其它运维与编程  |  留言簿
DNGuard HVM 2.71beta DNGuard Enterprise v2.80 released
未知  .Net中的数字类型四则运算的有趣问题
[ 发布日期:17年前 (2007-11-29) ]   [ 来自:rick@博客园 ] [分类:C# .Net编程]
看看下面的代码:
     sbyte sba, sbb,sbv;
            sba = 1;
            sbb = 2;
            sbv = sba + sbb;

            byte ba, bb, bv;
            ba = 1;
            bb = 2;
            bv = ba + bb;

            short sa, sb, sv;
            sa = 1;
            sb = 2;
            sv = sa + sb;

            ushort usa, usb, usv;
            usa = 1;
            usb = 2;
            usv = usa + usb;

            MessageBox.Show(string.Format("{0},{1},{2},{3}", sbv, bv, sv, usv));
你觉得这段代码能否正确执行?结果会怎样?

用VS2005打开项目测试一下你就会发现,这段代码会出现编译错误.
正确的代码应该如下:           
            sbyte sba, sbb,sbv;
            sba = 1;
            sbb = 2;
            sbv = (sbyte)(sba + sbb);

            byte ba, bb, bv;
            ba = 1;
            bb = 2;
            bv = (byte)(ba + bb);

            short sa, sb, sv;
            sa = 1;
            sb = 2;
            sv = (short)(sa + sb);

            ushort usa, usb, usv;
            usa = 1;
            usb = 2;
            usv = (ushort)(usa + usb);

            MessageBox.Show(string.Format("{0},{1},{2},{3}", sbv, bv, sv, usv));

这是什么原因呢?
其实CLR底层只支持 int,int64,native int, float , double几种数据类型.
像上面的sbyte,byte,short,ushort, clr底层是不支持的,在底层这些类型是用int表示的.
CLR的堆栈中压入的数字,最小是4字节,小于4字节的会根据其类型进行符号扩展或者0扩展为4字节int型.
这样四则运算的结果也是int型,最后再赋值需要进行强制类型转换.

分析一下编译后的IL代码就清楚了.

下面这个代码为什么能编译呢?
short sb;
sb=2;
sb += 1;
其实编译后的IL代码中最后赋值也包含了类型转换操作.
应该是编译器自动识别,然后自动添加的类型转换操作.

但是像上面的代码也编译出错,这个也能进行类型推断,自动添加数据类型转换啊.
不知道微软这么设计是bug还是基于其它因素的考虑?
引用通告地址 (0):
复制引用地址https://www.rickw.cn/trackback/217
复制引用地址https://www.rickw.cn/trackback/217/GBK
[ 分类:C# .Net编程  | 查看:3433 ]

暂时没有评论,快来发表一个评论吧。
发表评论
作者:   用户:[访客] 
评论:

表  情
禁止表情 | 禁止UBB | 禁止图片 | 识别链接
对不起,你没有权限上传附件!
验证:
 
PoweredBy R-Blog V1.00 © 2004-2024 WWW.RICKW.CN, Processed in second(s) , 7 queries    京ICP备17058477号-5