C# checked和unchecked详解
来源:互联网 发布:英语课文朗读软件 编辑:程序博客网 时间:2024/05/22 01:37
1、对基元类型执行的许多算术运算都可能造成溢出,有如下代码:
Byte b=100;b=(Byte)(b+200);
简单的解读上面的代码:
第一步,将所有的操作数都扩大至32位或者64位(根据操作系统的位数决定)。所以b和200(这两个值都不超过32位),首先转换成32位(假设当前操作系统是32位),然后加到一起。结果就是一个32位值(十进制300或者十六进制12C)。注意此时的值为一个32位的操作数,必须转型为一个byte。C#不会隐式地执行这个转型操作,这正是第二行代码需要强制转换为Byte的原因.如果不把结果值强制转换为Byte,代码如下:
byte b = 100;b = b +300;
如果将值强行转换为Byte,那么还会出现一个问题,就是值溢出的问题,Byte只能表示0~255范围的值,所以300超出了Byte的范围,值就溢出了.不同的语言以不同的方式处理溢出,C和C++不视溢出为错误,并允许值回滚.应用程序将若无其事的运行.相反,Microsoft Visual Basic总将溢出视为错误,并会在检测到溢出时抛出一个错误.
而CLR提供了一些特殊的IL指令,允许编译器选择它认为最正确的行为。CLR有一个add指令,将作用是将两个值加到一起,但不执行溢出检查。CLR还有一个add.ovf的指令,作用是将两个值加到一起,但会在抛出异常时抛出一个System.OverflowException异常。除了用于加法运算的这两个IL指令外,CLR还为减、乘和数据转换提供了类似的IL指令,分别是sub/sub.ovf,sub/sub.ovf和conv/conv.ovf。
也就是说C#允许程序员自己决定如何处理溢出,溢出检查默认是关闭的。因为这样能保证代码的运行效率,但是开发人员必须保证不会发生溢出,或者他们的代码能预见到这些溢出.
2、控制溢出的方法
第一种:打开/checked编译器开关.这个开关指示编译器在生成代码时,使用加、减、乘、除和转换指令的溢出检查版本也就是带.vof的版本,这样,在生成代码时,就会检查代码是否溢出.
下面是/checked编译器开关的打开方式:
第二种:就是用checked和unchecked关键字来控制溢出的检查与否,这体现的C#溢出检查的灵活性.
下面是一个在/checked编译器开关打开的情况下,使用unchecked关键字强制不检查unchecked包裹的代码的溢出问题,代码如下:
UInt32 a = unchecked((UInt32)(-1));Console.WriteLine(a); //一个很大的数
下面在/checked编译器开关关闭的情况下,使用checked关键字检查其包裹的代码的溢出问题,代码如下:
byte b = 100;b =checked((Byte)(b +300)); //溢出错误Console.WriteLine(b);
3、checked和unchecked语句
除了上面的checked和unchecked关键字外,checked和unchecked还可以是语句,它们造成一个块中的表达式就进行/不进行溢出检查.代码如下:
checked{ byte b = 100; b += 200;//在checked语句块内,可以直接使用+=操作符,编译器自动会把值转换为byte,前提200必须在byte范围内 Console.WriteLine(b);}
4、关于基元类型进行算术操作产生溢出的建议
a、在应用程序能够容忍checked运算造成的性能损失的情况下,尽可能的打开/checked编译器开关,保证程序的正常运行
b、尽量使用有符号整数(Int32,Int64),少使用无符号整数(UInt32,UInt64)
c、将不希望发生overflowException的代码块作用于checked关键字下,并捕获overflowException,并即时从异常中恢复.
d、c的反例,unchecked的用法.
- C# checked和unchecked详解
- C# checked 和 unchecked
- C# checked和unchecked
- C#中的checked和unchecked
- C#的checked和unchecked操作符
- C#的checked和unchecked操作符
- java checked和unchecked异常详解
- checked 和 unchecked exception
- checked和unchecked关键字
- C# 中的整数溢出检查 checked 和 unchecked
- C#中使用checked和unchecked整数运算
- C# checked和unchecked关键字与强制类型转换
- C# checked、unchecked操作符
- C# checked、unchecked操作符
- C# checked与unchecked用法
- C# checked、unchecked操作符
- C# checked与unchecked用法
- 详解Java中的checked异常和unchecked异常
- 操作系统-内存管理-内存空间的连续分配方式
- python中is和==
- java序列化
- 2017 ACM/ICPC Asia Regional Shenyang Online Ping Ping Ping 树链剖分+树状数组
- Linux下jdk的安装以及配置
- C# checked和unchecked详解
- 资讯精选 | 开发一套高可用的物联网设备分几步? zGlue:放着我来
- vue-router 学习笔记
- 设置网站ico图标的两种方法
- Java 内存模型及GC原理
- 无需第三方软件实现Mac支持ntfs读写的最简单操作
- ReactNative中SectionList实现条目GridView效果
- GitChat · 架构 | 为什么微服务实施那么难?如何高效推进微服务架构演进
- 计算机应用