为什么整型变量的值为'0xffffffff`>&燃气轮机;1 != 0x7fffff? int c=0xffffffff; printf(“%x\n”,(c)==(0xffffffff)); printf(“%x\n”,(c>>1)=(0xffffffff>>1));
第一个输出为为什么整型变量的值为'0xffffffff`>&燃气轮机;1 != 0x7fffff? int c=0xffffffff; printf(“%x\n”,(c)==(0xffffffff)); printf(“%x\n”,(c>>1)=(0xffffffff>>1));,c,C,第一个输出为1,但第二个输出为0。 和c>>1输出0xffffffff。但是为什么呢?整数常量0xffffffff的类型是无符号int。因此,当您对该值执行右移位时,值为0的位将从左移位 相反,c是一个int,包含一个负值。对负值执行右移是实现定义的,尽管大多数实现将通过从左移入值为1的位来保留符号 关于在比较正值和负值时打印1的原因: printf("%x\n", (c) == (0xffffffff)); 它与整数转换有关 当0xFFFFFF(无符号)被分配给c时,它
1
,但第二个输出为0
。
和
c>>1
输出0xffffffff
。但是为什么呢?整数常量0xffffffff
的类型是无符号int
。因此,当您对该值执行右移位时,值为0的位将从左移位
相反,c
是一个int
,包含一个负值。对负值执行右移是实现定义的,尽管大多数实现将通过从左移入值为1的位来保留符号
关于在比较正值和负值时打印1的原因:
printf("%x\n", (c) == (0xffffffff));
它与整数转换有关
当0xFFFFFF(无符号)被分配给c
时,它将进行实现定义的转换,因为该值超出范围。在2的补码系统中,这通常意味着表示将直接应用于目的地。现在c
的值为-1,表示为0xFFFFFF
现在进行比较。常量
0xffffffff
是无符号的,其值为232-1。将有符号值与大小相同的无符号值进行比较时,有符号值将转换为无符号值。这是通过将无符号int
+1的最大值与有符号值相加以将其置于范围内实现的(根据标准)。因此,有符号值-1被转换为无符号值232-1。这是与0xFFFFFF相同的值,因此比较结果为真。因为平台上的0xFFFFFF
是类型为unsigned int
的值。
因此0xffffffff>>1
等于0xffffffffU>>1
,即0x7fffffffU
将类型为unsigned int
的值赋给类型为int
的变量时,该值将转换为目标类型0xFFFFFF
即4294967295超出32位有符号整数的范围,因此自然无法按原样存储。但由于您的计算机使用两位补码系统,位将保持不变,即所有位都将被设置,但值被解释为-1而不是4294967295
负整数的右移行为在C标准中定义为实现。它作为算术右移,即使用符号扩展。因此,位表示ffffffff
右移1将导致ffffff
位表示;符号int表示值-1
最后,当您使用=
运算符将int
与无符号int
进行比较时,操作数将进行“常规算术转换”int
-1将转换为无符号int
,在两个补码系统上保留位模式,即ffffffff
,但是现在该值将被解释为4294967295,而不是-1。但该值与0x7fffffff(2147483647)不相等,后者具有
更让人困惑的是
c
的值不等于0xffffffff
,即使相等运算符返回true也是如此!c
的值将是-1,0xffffffff
的值是0xFFFFFFU
,即4294967295
,显然-1
和4294967295
之间的区别是4294967296!但正是由于有符号/无符号的比较,不同的值可以比较为相等的值,例如GCC将用-Wextra
发出警告:
warning: comparison of integer expressions of different signedness: ‘int’ and ‘unsigned int’ [-Wsign-compare]
5 | printf("%x\n", (c) == (0xffffffff));
| ^~
[venv][vrcappsdev][master✗]
要看到值确实是不同的,您需要将两侧强制转换为一个足够大的类型,以包含这两个值-long-long-int
是一个可移植的类型:
printf("%d\n", (long long int)c == (long long int)0xffffffff);
不会打印1。尝试打印c>>1
和0xffffffff>>1
int
和无符号int
。我同意:试着打印这些值以更好地检查它。c>>1
是0xffffffff
,0xffffffff>>1
是0x7ffffffff
@HanwGeek然后你应该问that@HanwGeek你不同意它们不相等吗?long-long-int
是可移植的吗?MSVC什么时候实现了long-long-int
?我怀疑仍然有人在使用MSVC版本,但该版本没有将long-long-int
作为标准类型。@EricPostFischil啊我在3小时前收到带外通知,但忘记修复:D