C# checked和unchecked 关键字详解
checked 和 unchecked关键字用来限定检查或者不检查数学运算溢出的;如果使用了checked发生数学运算溢出时会抛出OverflowException;如果使用了unchecked则不会检查溢出,算错了也不会报错。
1. 一段编译没通过的代码
|
1
|
int a = int.MaxValue * 2; |
以上代码段编译没有通过,在VS2010中会有一条红色的波浪线指出这段代码有问题:”The operation overflows at compile time in checked mode”。这说明了编译器会在编译时检查数学运算是否溢出。但是编译时能检查出溢出的情况仅限于使用常量的运算。2中的代码编译器就不报不出错误来了。
2. 一段编译通过但是不能得到正确结果的代码
|
1
2
3
|
int temp = int.MaxValue;int a = temp * 2;Console.Write(a); |
我先把常量int.MaxValue的值给了临时变量temp,然后使用临时变量乘以2计算结果赋值给a;这段代码是可以正常执行的,执行结果将输出 -2。
这说明在运行时默认情况程序是不会检查算术运算是否溢出的,cpu只管算,对于它来讲按规则算就是了,结果对不对不是他的错。
正常执行了,而结果是错误的,这是非常危险的情况,该如何避免这种危险呢?请看3
3. 使用checked关键字,溢出时报警
|
1
2
3
4
5
6
7
8
9
10
|
int temp = int.MaxValue;try{ int a = checked(temp * 2); Console.WriteLine(a);}catch (OverflowException){Console.WriteLine("溢出了,要处理哟");} |
使用checked关键字修饰temp*2的计算结果,并使用try catch在发生溢出时做处理。以上代码将输出:“溢出了,要处理哟”
问题是如果一段代码中有很多算术运算都需要做溢出检查,那会有很多checked修饰的表达式,怎么办呢?请看4
4. checked关键字可以修饰一个语句块,请看下面代码
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
int temp = int.MaxValue;try{ checked { int num = temp / 20; int a = temp * 2; int c = temp * 1000; }}catch (OverflowException){ Console.WriteLine("溢出了,要处理哟");} |
以上程序输出结果和3一样
5. checked在避免算术溢出方面很有用,那么unchecked呢,它有用吗?答案是肯定的,有时候我们不需要准确的计算结果,我们只是需要那么一个数而已,至于溢出不溢出的关系不大,比如说生成一个对象的HashCode,比如说根据一个算法计算出一个相对随机数,这都是不需要准确结果的。如下代码片段
|
1
2
3
4
5
6
7
8
9
10
11
12
|
class Person{ public string Name { get; set; } public string Title { get; set; } public override int GetHashCode() { return unchecked(Name.GetHashCode() + Title.GetHashCode()); }} |
unchecked也可以修饰语句块,其用法和checked完全一样。
6. checked和unchecked是可以嵌套使用的,虽然没啥意义。语句是否是checked以最近嵌套的checked或者unchecked决定
7. 从IL中看checked关键字
C#代码:
static void Main(string[] args){ int a = int.MaxValue; int b = a * 2; int c = checked(a * 2); int d = unchecked(a + 3); Console.Read();} |
对应IL
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 26 (0x1a)
.maxstack 2
.locals init ([0] int32 a,
[1] int32 b,
[2] int32 c,
[3] int32 d)
IL_0000: nop
IL_0001: ldc.i4 0x7fffffff
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldc.i4.2
IL_0009: mul
IL_000a: stloc.1
IL_000b: ldloc.0
IL_000c: ldc.i4.2
IL_000d: mul.ovf
IL_000e: stloc.2
IL_000f: ldloc.0
IL_0010: ldc.i4.3
IL_0011: add
IL_0012: stloc.3
IL_0013: call int32 [mscorlib]System.Console::Read()
IL_0018: pop
IL_0019: ret
} // end of method Program::Main
请看IL中的红色和绿色加重显示代码,可以看出使用checked时,IL的运算是mul.ovf;不使用checked或者使用unchecked时的IL运算函数是mul或者add,不带.ovf。
8. checked或者unchecked只影响其包围的语句,不会影响到包围的语句内调用函数的代码块,如下示例:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
static void Main(string[] args){ int a = int.MaxValue; int b = 20; checked { int c = TestMethod(a, b); Console.WriteLine(c); }}static int TestMethod(int a, int b){ return a * b;} |
上面代码将会正常执行,checked语句块并未起到应有的作用。
9. 全局开启或者关闭checked编译选项
在项目属性页上选择“生成”选项卡,然后点击“高级”按钮,选中“检查数学运算溢出”选项,如下示意图

总结:
checked和unchecked是两个不常用的关键字,但是他们俩是有用的,在需要的时候请记得用他们两位,另外建议测试时开启全局checked编译器选项。
转自:https://www.cnblogs.com/yukaizhao/archive/2011/08/09/csharp-checked-unchecked-keywords.html
C# checked和unchecked 关键字详解的更多相关文章
- 【转载】C/C++中extern关键字详解
1 基本解释:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义.此外extern也可用来进行链接指定. 也就是说extern ...
- python关键字详解
今天依旧在啃:<笨方法学python>,其中习题37是复习各种关键字.我本想百度一下记一下就ok了,但是百度出来第一个就Hongten的博客.我才意识到我也有博客,我应该学习他,把这些积累 ...
- c#关键字详解
c#关键字 关键字是对编译器有特殊意义的预定义的保留标识符.它们不能在程序中用作普通标识符,除非在它们前面加上@前缀. 第一部分 一.访问关键字:base,this base:访问基类的成员. 用 ...
- Java面试题04-final关键字详解
Java面试题04-final关键字详解 本篇博客将会讨论java中final关键字的含义,以及final用在什么地方,感觉看书总会有一些模糊,而且解释的不是很清楚,在此做个总结,以备准备面试的时候查 ...
- Objective-C 实用关键字详解1「面试、工作」看我就 🐒 了 ^_^.
在写项目 或 阅读别人的代码(一些优秀的源码)中,总能发现一些常见的关键字,随着编程经验的积累大部分还是知道是什么意思 的. 相信很多开发者跟我当初一样,只是基本的常用关键字定义属性会使用,但在关键字 ...
- java continue break 关键字 详解 区别 用法 标记 标签 使用 示例 联系
本文关键词: java continue break 关键字 详解 区别 用法 标记 标签 使用 示例 联系 跳出循环 带标签的continue和break 嵌套循环 深入continue ...
- mysql中文、英文别名排序问题,order by 关键字详解
order by 关键字详解: SELECT intcode AS 商品编码, product_title AS 名称, retailprice AS 零售价, purchaseprice AS ...
- Java多线程(三)—— synchronized关键字详解
一.多线程的同步 1.为什么要引入同步机制 在多线程环境中,可能会有两个甚至更多的线程试图同时访问一个有限的资源.必须对这种潜在资源冲突进行预防. 解决方法:在线程使用一个资源时为其加锁即可. 访问资 ...
- java关键字详解----static
Java Static关键字详解 提起static关键字,相信大家绝对不会陌生,但是,想要完全说明白,猛的一想,发现自己好像又说不太明白... ...比方说,昨天被一个同学问起的时候... ... ...
随机推荐
- luogu 3702 [SDOI2017]序列计数 矩阵乘法+容斥
现在看来这道题真的不难啊~ 正着求不好求,那就反着求:答案=总-全不是质数 这里有一个细节要特判:1不是质数,所以在算全不是质数的时候要特判1 code: #include <bits/stdc ...
- Cogs 1714. [POJ1741][男人八题]树上的点对(点分治)
[POJ1741][男人八题]树上的点对 ★★★ 输入文件:poj1741_tree.in 输出文件:poj1741_tree.out 简单对比 时间限制:1 s 内存限制:256 MB [题目描述] ...
- 【csp模拟赛九】--dfs3
这道题贪心错误:直接dfs就行,枚举新开一个还是往之前的里面塞 贪心代码(80): #include<cstdio> #include<algorithm> #include& ...
- linux系列(十六):which命令
1.命令格式: which 可执行文件名称 2.命令功能: which指令会在PATH变量指定的路径中,搜索某个系统命令的位置,并且返回第一个搜索结果. 3.命令参数: -n 指定文件名长度,指定的长 ...
- express搭建web服务器、路由、get、post请求、multer上传文件、EJS模板引擎的使用
express官网 postman工具下载地址 multer的npm文档地址 express模板引擎怎么使用 地址:http://www.expressjs.com.cn/guide/using- ...
- Ubuntu 14.04 改变文件或者文件夹的拥有者
只有系统管理者(root)才有这样的权限#将文件 file1.txt 的拥有者设为 runoob,群体的使用者 runoobgroupchown runoob:runoobgroup file1.tx ...
- Java基础系列 - JAVA集合ArrayList,Vector,HashMap,HashTable等使用
package com.test4; import java.util.*; /** * JAVA集合ArrayList,Vector,HashMap,HashTable等使用 */ public c ...
- windows2008服务器设置系统启动时程序自动运行
设置windows服务器启动时自动运行程序,而且不需要用户登录,就可以启动 首先准备好,程序的启动脚本文件或运行文件,如:start.bat 通过系统计划任务实现 1.开始----管理工具-----任 ...
- 使用RESTful风格开发
什么是RESTful风格? REST是REpresentational State Transfer的缩写(一般中文翻译为表述性状态转移),REST 是一种体系结构,而 HTTP 是一种包含了 RES ...
- Python数据预处理(sklearn.preprocessing)—归一化(MinMaxScaler),标准化(StandardScaler),正则化(Normalizer, normalize)
关于数据预处理的几个概念 归一化 (Normalization): 属性缩放到一个指定的最大和最小值(通常是1-0)之间,这可以通过preprocessing.MinMaxScaler类实现. 常 ...