int a = -534;
unsigned int b = (unsigned int)a;
printf("%d, %d", a, b);
Run Code Online (Sandbox Code Playgroud)
版画 -534, -534
为什么没有发生类型转换?
我期待它 -534, 534
如果我修改代码
int a = -534;
unsigned int b = (unsigned int)a;
if(a < b)
printf("%d, %d", a, b);
Run Code Online (Sandbox Code Playgroud)
它不打印任何东西......毕竟a不到b?
Tro*_*nic 15
因为你%d用于打印.使用%u无符号.由于printf是一个vararg函数,它不能知道参数的类型,而必须依赖于格式说明符.因此,你所做的类型转换没有效果.
首先,您不需要a强制转换:将的值隐式转换为unsigned int,并将其分配给b。因此,您的陈述等同于:
unsigned int b = a;
Run Code Online (Sandbox Code Playgroud)
现在,unsignedC和C ++ 中整数类型的一个重要属性是它们的值始终在[0,max ] 范围内,其中max for unsigned int是UINT_MAX(在中定义limits.h)。如果您分配的值不在该范围内,则会将其转换为该范围。因此,如果值是负数,则UINT_MAX+1重复添加以使其在[0,UINT_MAX] 范围内。对于上面的代码,就好像我们写了:unsigned int b = (UINT_MAX + a) + 1。这不等于-a(534)。
请注意,无论基础表示形式是二进制补码,二进制补码还是符号幅度(或任何其他奇异编码),以上都是正确的。可以看到类似的内容:
signed char c = -1;
unsigned int u = c;
printf("%u\n", u);
assert(u == UINT_MAX);
Run Code Online (Sandbox Code Playgroud)
在典型的带有4字节的二进制补码机上int,cis 0xff和uis 0xffffffff。编译器必须确保在将值-1分配给u时将其转换为等于的值UINT_MAX。
现在回到您的代码,printf格式字符串对于是错误的b。您应该使用%u。完成后,您会发现它显示的值UINT_MAX - 534 + 1不是534。
当用于比较运算符时<,由于bis unsigned int,a也将转换为unsigned int。给出b = a:更早的意思a < b是错误的:a因为unsigned int等于b。
假设您有一台补码机,并且这样做:
signed char c = -1;
unsigned char uc = c;
Run Code Online (Sandbox Code Playgroud)
假设char该机器上的(有符号或无符号)是8位。然后c,uc将存储以下值和位模式:
+----+------+-----------+
| c | -1 | 11111110 |
+----+------+-----------+
| uc | 255 | 11111111 |
+----+------+-----------+
Run Code Online (Sandbox Code Playgroud)
需要注意的是的位模式c和uc是不一样的。编译器必须确保在计算机上c具有的值-1和uc的值UCHAR_MAX255。