6.3使用checked和unchecked整数运算第2章讲过如何对基本数据类型(如int和double)使用二元算术操作符(如+和*)。我们还讲过,基本数据类型有一个固定的大小。例如,一个c#的int固定为32位。由于int的大小是固定的,所以能轻松推算出它支持的值的范围:-2 147 483 648~2 147 483 647。
提示:
要在代码中引用int的最小或最大值,请分别使用int.MinValue和int.MaxValue属性。
int的固定大小引发了一个问题。例如,在当前值已经为2147483647的一个int上加1,会发生什么情况?答案取决于应用程序是如何编译的。默认情况下,C#编译器会生成代码,允许计算悄悄地溢出。换言之,你将得到一个错误的答案(事实上,在最大值上加1,会溢出至最大的负数值,结果是-2 147 483 648)。这样做是出于对性能的考虑:在几乎所有程序中,整算术都是一种常见的运算,如果每个整数表达式都要进行溢出检查,将造成性能的严重下降。大多数时候,为此而承担的风险都是能够接受的,因为你知道(或者希望)自己的int值不会超过限制。但是,假如不想冒这个险,也可以启用溢出检查功能。
提示:在Visual Studio 2008中,为了启用或禁用溢出检查,可以设置项目属性。在”项目”菜单中,请选择”YourProject属性”选项(其中,YourProject是当前项目的名称)。在项目属性对话框中,单击”生成”标签。单击选项卡右下角的“高级”按钮。在随后出现的”高级生成设置”对话框中,勾选或撤选”检查运算上溢/下溢”项目即可。
无论如何编译一个应用程序,都可以使用checked和unchecked关键字选择性打开和关闭程序的一个特定部分的整数溢出检查。这些关键字将覆盖为这个项目指定的编译器选项。
6.3.1编写checked语句checked语句是指以checked关键字开头的一个代码块。checked语句中的任何整数运算溢出,都会抛出一个OverflowException异常,如下例所示:
int number=int.MaxValue;
checked
{
int willThrow=number++;
Console.WriteLine(“永远都执行不到这里”);
}
重要提示:只有直接放在checked块中的整数运算才会得到检查。例如,假如块中出现一个方法调用,就不会对调用的方法中的整数运算进行检查,还可以使用unchecked关键字来创建一个强制不检查溢出的语句块。一个unchecked块中的所有整数运算部不会检查,永远不会抛出OverflowException异常。例如:
int number=int.MaxValue;
unchecked
{
int wontThrow=number++;
Console.WriteLine(“会执行到这里”);
}
6.3.2编写checked表达式使用checked和unchecked关键字,还可以控制对单独的整数表达式的溢出检查。为此,只需使用圆括号将表达式封闭起来,并在之前附加checked或unchecked关键字。如下例所示:
int wontThrow unchecked(int.MaxValue+1);
inc wontThrow= checked (int.MaxValue+1}.
复合操作符(例如+=和-=)和递增(++)递减(--)操作符都是算术操作符,它们都可以使用checked和unchecked关键字来控制。记住,x+=y等同于x=x+y。
重要提示:不能使用checked和unchecked关键字来控制浮点(非整数)运算。checked和 unchecked关键字只能适用于对int和long等数据类型执行的整数运算.浮点运算永远不会抛出OverflowException--即使让一个浮点数除以0.0NET Framework有专门表示无穷大的机制)。
通过以下练习,可体验如何使用Visual Studi0 2008来执行checked算术运算。
使用checked表达式l,返回Visual Studio 2008编程环境。
2,在“调试”菜单中选择“开始执行(小调试)”。接着,我们准备尝试让两个较大的数相乘。
3,在left operand文本框中输入9876543,在right operand文本框中也输入9876543,从操作符区域选择“+ Multiplication”(乘),单击Calculate按钮。窗体上的Result文本框将显示值-1 195 595 903。这是一个负数,所以肯定是不正确的。之所以得到这个错误码的结果,是因为在执行乘法运算时,悄悄地溢出了int类型的32位限制。
4,单击Quit按钮,返回Visual Studi0 2008编程环境。
5,在“代码和文本编辑器”窗口显示Windowl.xaml.cs的代码,找到multiplyValues方法:
private int multiplyValues(int leftHandSide,int rightHandSide)
{
expression.Text=leftHandSide.ToString()+”*”+rightHandSide.ToString();
return leftHandSide*rightHandSide;
}
在return语句中,包含的正是悄悄地发生了溢出的乘法运算。
6,编辑return语句,对表达式执行checked运算:
rerurn checked( leftHandSide*rightHandSide);
这样就实现了对乘法运算的检查。如果发生溢出.将抛出一个OverflowException异常。而不是十分猥琐地返回一个错误答案。
7,在“代码和文本编辑器”窗口中找到calculateClick方法。
8,在现有的FormatException catch处理程序之后,紧接着添加以下catch处理程序:
catch (OverflowException oEx)
{
result.Text=oEx.Message;
}
提示:这个catch处理程序的逻辑就是FormatException catch处理程序的逻辑,然而,仍有必要对这两个处理程序进行区分,而不是写一个泛化的Exception catch处理程序,因为将来可能决定以不同的方式采处理这些异常。
9,在“调试”菜单中选择“开始执行(不调试)”,生成并运行应用程序。
10,在left operand文本框中输入9876543,在right operand文本框中也输入9876543,在操作符区域中选择“* Multiplication”,单击Calculate按钮。第二个catch处理程序将成功捕捉OverflowException异常,并在Result文本框中显示一条消息:“算术运算导致溢出”。
11,单击Quit按钮,返回Visual Studi0 2008编程环境