对于第一条输出,maximum+1后,刚好溢出,想像一下maximum的二进制表示就可以知道。
maximum的二进制表示为32位(1个0加32个1,由于是signed int,首位是符号位):01111111111111111111111111111111
这时+1,可想而知是unsigned int类型最大的负数值,即-(maximum+1)=-2147483648
对于第二条输出,由于maximum是unsigned int的二进制表示为32个1,即:11111111111111111111111111111111
这时+1,变为1后面加32个0,多出的高位都截掉,就剩下32个0了,即溢出后的值为0
为什么如下的代码不对?
int a = 1000, b = 1000; long int c = a * b;因为根据C的整型提升规则,乘法是用int进行的,而其结果可能会在提升或赋值给左边的long int型之前溢出或被截短。
以上是直接打印,由于故意设置了不兼容的打印格式(在IDE上会有Warning!),所以打印出的数值与原可能的预期不符,对于这种转换上的溢出,其实是丢失了高位,取低位的值。以long big=65537为例,它占4字节32位,它的二进制表示: 0000 0000 0000 0000 0001 0000 0000 0000 0001。而short 占用内存空间2个字节,也就是16个二进制位。这时截取低16位,所以得:0000 0000 0000 0001 = 1。由于int也是占4个字节32位,所以换成%d打印,结果也是对的。对于unsigned in un而言,道理是一样的。
由于C中int与char是一样的,只是一个占4byte,一个占1byte,下图展示了int转char时高位截掉取低8位的情况:
所以printf("%c",336);得出的结果是字符'P'。
总则:溢出后取低位。
可参见:关于整数与浮点数二进制表示,获取更多相关知识。
