C#每天一学之checked&unchecked

checked和unchecked操作符用于整型算术运算时控制当前环境中的溢出检查。下列运算参与了checked和unchecked检查(操作数均为整数):

1)  预定义的++和―― 一元运算符。

2)  预定义的-一元运算符。

3)  预定义的+、-、×、/等二元操作符。

4)  从一种整型到另一种整型的显示数据转换。

 

(一)使用checked

若运算是常量表达式,则产生编译错误:The operation overflows at complie time in checked mode.

若运算是非常量表达式,则运行时会抛出一个溢出异常:OverFlowException异常。

checked 的用法可以是checked(//运算代码),也可以是checked{//运算代码},一般都是小量的代码。

先看下面代码:

            Byte b = 100;

            b 
+= 200;

            Console.WriteLine(b.ToString());

 结果并不是我们预想的输出300,输出是44。假设我们用于计算那是多么的危险,上述代码编译时编译器并没有告诉程序员运算溢出。而是偷偷的干了坏事...

下面我们加上checked,看效果如何:

            byte b = 200;
            
checked
            { 
                b 
+= 200;
            }
            Console.WriteLine( b.ToString());

可以看到程序并没有输出,而是在运行时抛出OverflowException,干了try catch的事情,告诉程序员说运算溢出了,赶快修bug。在运行时才抛出异常,在测试中带来些许麻烦,那么如何在程序编译时就抛出错误呢,事实上编译时是不能确定运算结果的,也就是说运算结果是在运行是才能确定,所以只有在运行时checked才做运算溢出检查。但是下列代码是编译不通过的(地球人都知道)

            byte b;
            
checked
            {
                b 
= 256;
            }
            Console.WriteLine( b.ToString());

输出错误 Constant value '300' cannot be converted to a 'byte' ,byte的范围是0~255嘛,编译当然报错。

需要指出的是,看下面代码:

Byte b = 100;
= (Byte)checked(b + 200);//不抛出System.OverflowException异常信息

这里解释一下,因为 b+ 200 的结果是int32,checked是对int32的检查当然没有运算溢出,但是再将结果转换成byte时没有checked,所以返回值会被截掉不符合目标类型的高位,输出不正确的结果。

 

(二)使用unchecked

无论运算是否是常量表达式,都没有编译错误或是运行时异常发生,只是返回值被截掉不符合目标类型的高位,用法类似checked。

参考资料:

[1]C#中的checked、unchecked操作符http://www.knowsky.com/301786.html

[2]基元类型和Checked、UnChecked操作符的使用 http://www.cnblogs.com/noviceliu/archive/2009/03/11/1408461.html

 

 

posted @ 2009-04-06 22:45  yangbinhe  阅读(493)  评论(0编辑  收藏  举报