今天看到一题关于位操作的面试题,看了所谓的答案后还是比较迷茫,于是网上搜索了下,加上自己理解整理如下
题目: unsigned short A = 10; printf("~A = %u/n", ~A); char c=128; printf("c=%d/n",c); 输出多少?
首先看第一步,类型位unsigned short,windows 32 位机上是16位,两字节,也就是说A:0000 0000 0000 1010
~A:1111 1111 1111 0101, 整数(char, short, int, long)进行四则运算或移位操作的中间结果用32bits寄存器保存,所以 ~A:1111 1111 1111 1111 1111 1111 1111 0101,当输出printf为%d时,有符号十进制,则 ~A因为是负数,根据补码转换:1000 0000 0000 0000 0000 0000 0000 1010 +1 = 1000 0000 0000 0000 0000 0000 0000 1011 = - 11;当输出printf为%u,即无符号十进制时,无符号位,二进制到十进制转换: ~A:1111 1111 1111 1111 1111 1111 1111 0101 = 4294967285.
第二步,char c = 128; c = 1000 0000,%d带符号十进制,c即为负数,c = 1111 1111 + 1 = 1 0000 0000由于printf调用 push指令,只能是32bits操作数,因此printf内部无法区分到底参数是何种类型(char,short, int, long),只能通过%d,知道是有符号int。所以输出为-128.
例子:
#include <stdio.h>;
unsigned short us;
main()
{
us = 0xffff;
printf("sizeof(us) = %d %d/n", sizeof(us), us << 16);
}
输出2,-65536,此题中us<<16后值并非为0,实际值由于:printf调用时候用的是32位的寄存器,移位后
1111 1111 1111 1111 0000 0000 0000 0000,根据负数补码原则输出即为-65536
#include <stdio.h>;
unsigned short us;
main()
{
us = 0xffff;
us <<= 16;
printf("sizeof(us) = %d %d/n", sizeof(us), us );
}
输出结果为2,0
us<<=16 结果为 1111 1111 1111 1111 0000 0000 0000 0000但是类型截断为0000 0000 0000 0000.
本文详细解析了一道关于位操作的面试题,包括unsigned short类型的取反运算和char类型的正负表示转换。通过具体示例解释了不同类型的位运算结果及输出格式的影响。
2102

被折叠的 条评论
为什么被折叠?



