C:如果x是char类型,那么在x=~x中(详细)会发生什么?
如果我们有以下代码:C:如果x是char类型,那么在x=~x中(详细)会发生什么?,c,type-conversion,operators,C,Type Conversion,Operators,如果我们有以下代码: char x = -1; x =~x; 在带有MS VS编译器(部分支持C99)的x86平台上,当它运行时会发生什么详细情况 据我所知,发生以下情况(如果我错了,请纠正我): x被分配值-1,该值由位模式0xff表示,因为字符由一个字节表示 ~运算符将x提升为int,也就是说,它在内部使用位模式0xFFFFFF ~运算符的结果是0x00000000(int类型) 要执行分配,应(主要)应用整数提升。因为在我们的例子中,右边的操作数是int,所以不会发生转换。左侧的操作数
char x = -1;
x =~x;
在带有MS VS编译器(部分支持C99)的x86平台上,当它运行时会发生什么详细情况
据我所知,发生以下情况(如果我错了,请纠正我):
- x被分配值-1,该值由位模式0xff表示,因为字符由一个字节表示
- ~运算符将x提升为int,也就是说,它在内部使用位模式0xFFFFFF
- ~运算符的结果是0x00000000(int类型)
- 要执行分配,应(主要)应用整数提升。因为在我们的例子中,右边的操作数是int,所以不会发生转换。左侧的操作数转换为int。赋值结果为0x00000000
- 作为副作用,分配的左侧被分配值0x00000000。由于x是char类型,因此存在另一个隐式转换,它将0x00000000转换为0x00
事实上发生的事情太多了,我觉得有些困惑。特别是:我对最后一次隐式转换(int到char)的理解正确吗?如果分配的结果不能存储在字符中,会发生什么情况?确实
~x
是int
类型
如果char
是unsigned
,则返回到char
的转换是明确定义的。当然,如果值在char
支持的范围内,那么它也是定义良好的
如果char
是有符号的
,则~x
到char
的转换是实现定义的,并且可能会引发实现定义的信号
在您的例子中,您有一个带有2的补码int
和2的补码char
,因此~x
被观察为0的平台
请注意,MSVC并不完全支持任何C标准,它也不声称支持。您几乎是正确的,但遗漏了
char
具有实现定义的签名。它可以是有符号的,也可以是无符号的,这取决于编译器
在这两种情况下,8位2的补码字符的位模式实际上是0xFF,而不管其符号性如何。但是如果char
是有符号的,整数提升将保留符号,并且在32位计算机上仍然有值-1
,二进制0xFFFFFF。但是如果char
是无符号的,-1
将在赋值时转换为255
,整数提升将给出255
(0x000000FF
)。所以你会得到不同的结果
关于~
的整数提升,它的右侧只有一个运算符,并且该运算符已提升
最后,将结果分配回char
,结果将再次取决于签名。在从int
赋值到char
时,将有一个隐式的“左值转换”。结果是实现定义的-很可能得到int
的最低有效字节
从中我们可以学到:
- 切勿将
用于存储整数值或算术运算。仅用于存储字符。相反,请使用char
uint8\u t
- 切勿对可能有符号的操作数或通过隐式提升进行静默签名的操作数执行位算术李>
- 除非操作数是
或更大的无符号类型,否则~运算符尤其危险无符号int
1
是类型为int
的整数常量-
将该值取反为-1,并保持为int
-1被分配给字符x
。如果该char
已签名,则x
的值为-1。如果char
是无符号的,x
接受char\u MAX
的值,该值也是UCHAR\u MAX
。“位模式0xff”在这里还不相关
~运算符将x提升为int,也就是说,它在内部使用位模式0xFFFFFF
x
被提升为int
(或unsigned
,在CHAR\u MAX
=UINT\u MAX
的罕见机器上,我们将忽略这一点)。int
至少为16位。当-1的值被编码为绝大多数公共2的补码时,它是一个全1位模式。(其他可能的编码-我们也将忽略这一点)。如果x
的值为UCHAR\u MAX
,则x
将具有位模式00…00 1111 1111
——假设为8位char
。其他宽度可能-另一件我们将忽略的事情
~运算符的结果是0x00000000(int类型)
是,(除非CHAR\u MAX==UINT\u MAX
,在这种情况下,它是unsigned
且值为11…11 0000 0000)
要执行分配,应(主要)应用整数提升。因为在我们的例子中,右边的操作数是int,所以不会发生转换。左侧的操作数转换为int。赋值结果为0x00000000
由于分配原因,此处没有整数促销。由于~
,促销已发生。将发生类型更改,将int
分配给char
。那不是晋升。结果的类型为char
。作为缩小范围的一部分,0的值不会出现范围问题,并导致值为0,然后键入char
。11…11 0000 0000的值将通过实现定义的行为,可能会导致值0,并且肯定会键入char
代码是b