C语言中的流型溢出
执行上述语句后,C语言中的流型溢出,c,casting,overflow,C,Casting,Overflow,执行上述语句后,c有什么值 我无法解码解决这个问题的过程,提示是使用二进制加法。如果字符是8位无符号的,结果是2,即258%256 如果字符是有符号的,则结果是未定义的实现定义。简介 有两种实际情况需要考虑: char为无符号八位。因此,结果是2 char是有符号的八位字符。为此,将生成实现定义的结果或引发实现定义的信号 字符类型为无符号和八位 在这种情况下,charc=250很简单;它将c初始化为250。然后,inc+=8,该语句相当于c=c+8。在此语句中,c被提升为int,并执行加法,
c
有什么值
我无法解码解决这个问题的过程,提示是使用二进制加法。如果
字符是8位无符号的
,结果是2
,即258%256
如果字符是有符号的
,则结果是未定义的实现定义。简介
有两种实际情况需要考虑:
为无符号八位。因此,结果是2char
是有符号的八位字符。为此,将生成实现定义的结果或引发实现定义的信号char
charc=250代码>很简单;它将c
初始化为250。然后,inc+=8
,该语句相当于c=c+8代码>。在此语句中,c
被提升为int
,并执行加法,结果是258。最后,必须将此结果转换为char
以存储在c
中
转换为无符号类型的规则是将值调整为可以表示的“比最大值多一个”。也就是说,对于最大值为255的无符号char
,我们加上或减去256以生成一个可表示的值。所以258变成了258−256=2,并且c
设置为2
字符类型为有符号和八位
在这种情况下,charc=250代码>尝试使用它无法表示的值初始化c
。根据C 2018 6.7.9 11,初始化的执行类似于分配。根据6.5.16.1.2,赋值将值转换为左操作数的类型(左值转换后)。根据6.3.1.3,无法表示为有符号类型的值的转换由实现定义:
否则,新类型已签名,且无法在其中表示值;要么结果是实现定义的,要么引发实现定义的信号
假设执行持续超过char c=250代码>至c+=8代码>,然后将8添加到c
初始化为的任何值。这不能溢出,因为操作数升级为int
类型,并且任何char
值加8都可以在int
中表示。如果加法结果可在char
中表示,则将其存储在c
中。否则,转换规则将再次应用:结果是实现定义的或引发实现定义的信号
假设情况
这些情况在现代实践中很少或从未发生过
如果char
是有符号的九位,那么250是可表示的,因此c
被初始化为250。然后,inc+=8
,该加法产生的结果在字符中不可表示(最大值为255),因此上述转换规则适用,结果为实现定义的结果或引发实现定义的结果
如果char
大于9位,则不会发生错误,c
最终为258位
如果char
与int
的宽度相同(在堆栈溢出的其他地方讨论了一种假设可能性),并且char c=250代码>更改为,例如,charc=INT_MAX-5
,则c
将被无问题地初始化,但c+=8代码>将在运算过程中溢出,然后行为不由C标准定义。非常感谢Weather Vane!!此外,很明显%取的是余数值(如果我没有错的话)。那么,有没有任何可能的方法来解决使用二进制加法。如果char是有符号的,为什么结果是未定义的?希望不久能收到您的来信。@Nikhil二进制加法是1111010+0000 1000=1 0000 0010
,模数可以看作是8位的截断,剩下的0000 0010
是十进制的2
@Eric Postdischil:先生,请告诉我算术溢出规则和转换规则之间的区别。C11标准草案n1570:6.3转换6.3.1算术操作数6.3.1.3有符号和无符号整数3否则,新类型是有符号的,不能在其中表示值;要么结果是实现定义的,要么引发实现定义的信号。注:实施defined@Kikky:C标准(2018和2011版本)第6.3条中的规则管理转换,即当值从一种类型更改为另一种类型时发生的转换。这样的转换会自动发生在赋值、初始化、函数调用参数和其他一些地方。算术溢出是指当算术运算的数学结果在用于算术运算的类型中不可表示时发生的情况。适用不同的规则;数学结果不会自动转换为必要的类型。假设c
有符号,则根据c标准,溢出未定义。在许多实现中,将c
设置为250将溢出到-6,然后添加8将使c
2。这取决于实现。非常感谢!我仍然想问,有没有可能用二进制加法来解决这个问题?使用二进制加法的提示是250是11111010,8是1000,它们的和是100000100,也就是9位。如果char
仅包含最后八位,则前一个1将丢失,值为00000010,因此结果为2。但是,这个提示忽略了C的规则。如果char
是无符号的,那么这个算术的二进制视图就可以了;C的模包装规则相当于丢弃高位。如果char
已签名,则C的规则可能与此二进制视图不同;一个实现可以做其他事情
char c = 250;
c += 8;