题目一:
int main() { char a = -1; signed char b = -1; unsigned char c = -1; printf("a = %d,b = %d, c = %d", a, b, c); return 0; }
答案:a=-1, b=-1, c=255
解析:-1的补码为11111111 11111111 11111111 11111111存入char中(无论有无符号)都是发生截断得11111111 。于是以整型的方式输出要整型提升,有符号提升符号位,无符号提升0,故a和b提升后的补码依然是11111111 11111111 11111111 11111111,以原码输出为-1,c是unsigned,其补码是00000000 00000000 00000000 11111111,无符号原反补相同,为255.
题目2:
int main() { char a = -128; printf("%d\n", a); printf("%u", a); return 0; } int main() { char a = 128; printf("%d\n", a); printf("%u", a); return 0; }
答案:两个程序答案一样,为-128 4294967168
解析:128和-128存入char中都是截断为 1000 0000,以整型输出都是整型提升首位1,得到补码,原码以%d输出都为-128.
然后两个都是char整型提升为 11111111 11111111 11111111 10000000,再以无符号输出为4294967168
题目3:
int main() { int i = -20; unsigned int j = 10; printf("%d\n", i + j); return 0; }
答案:-10
解析:两数相加会算数转换为unsigned int。
-20的原码为10000000 00000000 00000000 00010100
-20的补码为111111111 11111111 11111111 11101100
10的补码和原码相同为0000000 00000000 00000000 00001010
相加补码为11111111 11111111 11111111 11110110 (unsigned)
%d整型的原码为1000000 00000000 00000000 00001010即-10
题目四:
int main() { unsigned int i; for (i = 9; i >= 0; i--) { printf("%u\n", i); } return 0; }
答案:死循环
解析:%u是无符号故不可能会退出循环,变为-1的时候%u为4294967295,接着循环。
题目5:
#include <string.h> int main() { char a[1000]; int i; for (i = 0; i < 1000; i++) { a[i] = -1 - i; } printf("%d\n", strlen(a)); return 0; }
答案:255
解析:strlen函数计算' \0 '之前的数,也就是0,char数组(范围127— -128)开始从-1 —>-128,127,126—>2,1,0—>-1...循环也就是-1到-128加上127到0之间的数的和为255。由于char -128的二进制补码是10000000(规定),减一为0111 1111 = 127。
题目6:
unsigned char i = 0; int main() { for (i = 0; i <= 255; i++) printf("hello world\n"); return 0; }
答案:循环打印输出hello world
解析:无符号char范围为0-255,255+1= 0,255的补码为 1111 1111+1截断为+1(0000 0000).