当前位置:   article > 正文

c++算术溢出_2.2.3 C#8.0教程 溢出检查机制 checked关键字

c++ unchecked

本节课重点说一下关于数据范围溢出的问题。我将会为大家介绍两个关键字 checkedunchecked 。请注意下图1.是否是你想要的结果?

b350cbe7a88367ee59b79b49e114159c.png

图1. 注意计算内容 与 输出结果

当在变量 i 的值是 2147483647 时,在其基础上 +1 。结果为:-2147483648 !是负数!是 int 类型的最小值!你是否希望出现这个结果,如果你认为这是个意外,不应该出现,那么你要学习 checked 关键字!如果你觉得这很正常,而且你需要得到的就是这个计算结果,那你需要了解 unchecked 关键字!

checked 有溢出?抛异常!

在块语句或表达式的前面,添加 checked 关键字,使所使其成为 checked context(检查上下文)状态。这意味着在运行时检查某些算术操作(包括强制类型转换)是否存在范围溢出。如果在检查的上下文中将值强制转换为整数类型,并且值过高或过低而无法匹配,则会发生错误—代码将抛出 System.OverflowException 异常。这时可使用 try…catch…捕获后进行处理。如下例所示:

20b33d660e457592a24e8248e0b09d8d.png

图2. 根本就不再执行 15 行以后语句了

由图2.示例我们可以看到,当我们在变量 i 最大值(用 int.MaxValue 属性获得)的基础上进行了 +1 操作,导致溢出!这时就会被 checked 检查到,抛出 OverflowException 异常,捕获后用户可以自行处理。但一定要注意,在执行到 i=i+1 抛出异常后,直接执行 catch 块语句,不会再执行 try 块语句了。未来讲 try...catch...时细说。所以第16行根本没有执行。

有小伙伴会觉得,这个异常抛的很正常啊,难道 checked 真的起作用啦?下面截图3.显示未添加 checked 机制的结果。加法运算符完美的进行了运算,精确的将二进制结果显示出来。

98af96e9c44b5d92268d819db992e417.png

图3.终端输出结果 -2147483648

图3.展示的结果说明编译器未发现错误(本身也确实没有错误),所以正确执行,得出了编译器认为的正确结果!为啥 最大值+1=最小值 ?计算机会鄙视你,问你为什么当初把它设计为二进制的。

既然不添加 checked 就不会检查溢出状态,为啥还要有 unchecked ?

unchecked 强制不检查溢出!

虽然在我们的城市里,充满了阳光与希望。当发生问题后,警察‍♀️叔叔、消防‍队员会第一时间出现帮助我们解决问题。但就像硬币有两个面一样,依然会有邪恶势力的存在。unchecked 就是他们的保护伞。一般情况下,unchecked 会嵌套在 checked 中,当要求所有人都遵纪守法,但个别人却需要获得豁免权时,就要对这少部分人启用 unchecked 。如下示例:

static void Main(string[] args){    #pragma warning disable CS0219    int x=0;    int y=0;    try    {        checked        {            unchecked            {                x=int.MaxValue+1;                Console.WriteLine(x);            }        }    }    catch(OverflowException)    {        Console.WriteLine("我们抓住了溢出!");    }}
6576959d25f7abd0ff03851366f6c90a.png

图4. unchecked块变成了“法外之地”

如图4.所示,unchecked { .. } 代码块中的所有表达式与变量均不会收到“溢出”检查。无论是否溢出,都不会抛出异常。虽然在外层已经设置了 checked 关键字,但显然 unchecked 不买账,强制取消了 checked 设置的溢出检查机制。所以 checked 代码块内的变量 x 经计算后,虽然溢出,但不会抛出。

但如下图5.所示,不在 unchecked 内的变量 y 如果溢出,则抛出异常:

b3071deeab85efe32fd3e3ab7904e79f.png

图5. x被豁免 y被抓住

OK,关于 checked 与 unchecked 的关系我们通过图5.已经一目了然。checked 就像警察,维护整个社会秩序,而 unchecked 就像黑涩会,虽然与警察对着干,但如果这个社会没有警察,也就没有了所谓的黑涩会。

checked 的其他用法与实际应用

除了检查语句块中计算是否存在溢出外,还可以应用在表达式中,如下所示:

int result = checked(a + b) + c;
9d3c3c444c72a1ed976ab6e850b942b2.png

图6. checked 其他用法

如图6.所示,checked 还可以应用在表达式中,便捷的检查溢出情况。

总的来说,checked context 机制的使用频率还是比较低的。很多情况下,编译器直接报错,不予编译,而不会抛出异常。

但在某些情况下,如大规模数学运算中,大数值会频繁使用,为确保意外情况的发生,最好还是使用 checked 机制及时检查其中可能会发生的溢出问题。严谨,是每个程序员必须要崇拜的词汇!

请注意,检查成本会使单个整数操作慢上几倍。它对应用程序的整体影响会更小,因为程序不会把它们的全部时间都花在执行算术上,但代价可能仍然不小。当然,对于任何性能问题,您都应该度量实际影响。您可能会发现,性能成本是一个可以接受的价格,以保证您将发现意外溢出。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小桥流水78/article/detail/1015318
推荐阅读
相关标签
  

闽ICP备14008679号