这会导致溢出吗?如果没有,那为什么不呢?因为“字节”类型仍将保持 8 位大小,并且如果它不会导致溢出,那么这是否意味着“强制转换”将“字节”类型在内存中的分配从 8 位增加到 32 位?..最终类型转换 [implicit] 实际上是如何工作的?
//a part of c# program
byte b = 100;
b = (Byte)(b + 200);
Console.WriteLine("VALUE OF BYTE TYPE'S OBJECT {0}",b);
//end
如果表达式产生的值超出目标类型的范围,则结果将被截断。
如果您想知道您的代码是否产生溢出,您应该使用检查语句 ( msdn ):
checked
{
byte b = 100;
b = (Byte)(b + 200);
Debug.WriteLine("VALUE OF BYTE TYPE'S OBJECT {0}", b);
}
隐式b+200
转换是. 就像 MSDN 文档说的那样,这隐含地变成了一个 int,等于 300。然后显式转换为字节,将其截断为 8 位。正如 kmatyaszek 建议的那样,您可以在运行时在checked
块内启用溢出检查。
考虑如下编写的代码段:
byte b = 100;
Console.WriteLine(b);
b = (Byte)(b + 200);
Console.WriteLine(b);
此代码将分别输出100
和44
。当这段代码执行时,实际发生的是加法运算导致大于 8 位的值,但程序并不关心,只取最后 1 个字节(例如 32 位值中的最后 8 位)
编辑:忘记提及执行该操作时不会导致溢出错误/异常。考虑代码:
b = Byte.MaxValue;
Console.WriteLine(b);
b++;
Console.WriteLine(b);
哪个输出255
& 0
。
但是,此代码将:
b = Byte.MaxValue;
Console.WriteLine(b);
b = checked((byte)(b + 1));
Console.WriteLine(b);
看:
不,因为当您执行显式转换时(并且您必须这样做,因为它隐式变为 int)就像您对编译器说“是的,我知道我在做什么,无论如何都要做”,所以结果将是(300 - 256 = 44),因此要导致溢出异常,您需要在适当的 try/catch 块中添加这样的已检查关键字:
try
{
byte b = 100;
b = checked((byte)(b + 200));
Console.WriteLine("VALUE OF BYTE TYPE'S OBJECT {0}", b);
}
catch(OverFlowException e)
{
Console.WriteLine(e.Message);
}
请参阅 C# 语言规范:
7.6.12 已检查和未检查的运算符
以下操作受已检查和未检查运算符和语句建立的溢出检查上下文的影响:
...
•从一种整数类型到另一种整数类型,或从浮点数或双精度数到整数的显式数字转换(第 6.2.1 节)类型。当上述操作之一产生的结果太大而无法在目标类型中表示时,执行操作的上下文将控制结果行为:
...
• 在未经检查的上下文中,通过丢弃任何高位来截断结果-order 位 *不适合目标类型*。对于未被任何已检查或未检查的运算符或语句包围的非常量表达式(在运行时计算的表达式),默认溢出检查上下文是未检查的 ,除非外部因素(例如编译器切换和执行环境配置)需要检查评估。
这 -(byte)
进行显式数字转换int
,默认情况下在未经检查的上下文中运行,因此截断结果。