1.
#include<stdio.h> int main() { char a = -1; signed char b = -1; unsigned char c = -1; printf("a=%d,b=%d,c=%d", a, b, c); // a=-1,b=-1,c=255 return 0; }
//解析:
-1占4个字节,而char类型大小是1个字节,所以这时要发生截断
10000000000000000000000000000001 ----原码
11111111111111111111111111111110 ----反码
11111111111111111111111111111111 ----补码
截断后
a ---> 11111111
同理
b ---> 11111111
c ---> 11111111
在内存中存储的是补码,各占8字节,但是打印的是用%d的形式打印的,所以要发生整型提升
char <----> signed char
a就是有符号的char,所以a的最高位就是符号位1,整型提升补1
a ---> 11111111111111111111111111111111 提升后的补码,但打印的是原码。
11111111111111111111111111111110 反码
10000000000000000000000000000001 原码
a=-1,同理b=-1
c ---> 11111111 是无符号的char类型,所以最高位1就不是符号位,整型提升补0
c ---> 00000000000000000000000011111111 整型提升后补码,是正数,所以原码反码补码相同
将c转成10进制就是255 c=255
2.
#include<stdio.h> int main() { char a = -128; printf("%u\n", a); //4294967168 return 0; }
// 解析:
-128的二进制表示为:
10000000000000000000000010000000 --->原码
11111111111111111111111101111111 --->反码
11111111111111111111111110000000 --->补码
因为char类型,发生截断,最多存放1个字节,即:
a---> 10000000
因为打印%u的类型,无符号整型,发生整型提升,所以最高位1就是符号位,补1
a---> 11111111111111111111111110000000
正是因为是无符号打印,所以判定11111111111111111111111110000000就是个正数,原反补均相同
转换成10进制打印下就是4294967168
3.
#include<stdio.h> int main() { char a = 128; printf("%u\n", a); return 0; }
//解析:
a的补码
01111111111111111111111110000000 --->a的补码
截断
10000000
整型提升
11111111111111111111111110000000
同上
4.
#include<stdio.h> int main() { int i = -20; unsigned int j = 10; printf("%d\n", i + j); // -10 return 0; }
// 解析:
i=-20:
10000000000000000000000000010100 原码
11111111111111111111111111101011 反码
11111111111111111111111111101100 补码
j=10:
00000000000000000000000000001010 原码-反码-补码
i+j:
11111111111111111111111111110110 补码
11111111111111111111111111110101 反码
10000000000000000000000000001010 原码
转换成10进制:
i + j = -10
5.
#include<stdio.h> #include<windows.h> int main() { unsigned int i; for (i = 9; i >= 0; i--) { printf("%u\n", i); // 死循环 Sleep(1000); } return 0; }
// 解析
当i--到-1时,-1的二进制表示为:
10000000000000000000000000000001 原码
11111111111111111111111111111110 反码
11111111111111111111111111111111 补码
因为%u打印,所以11111111111111111111111111111111全是有效位,即位正数,输出的原码 等于反码
转成10进制,就是一个很大的数字,以此类推陷入死循环。
6.
#include<stdio.h> int main() { char a[1000]; int i; for (i = 0; i < 1000; i++) { a[i] = -1 - i; } printf("%d", strlen(a)); // 255 return 0; }
理解这道题需要清楚一个char类型到底能放什么数值
类似的,short也有类似的性质:
同理int等等
7.
#include<stdio.h> unsigned char i = 0; int main() { for (i = 1; i <= 255; i++) { printf("hello world\n"); //死循环打印hello world } return 0; }
// 解析
这道题目的做法跟上一道题目类似,都涉及到了char类型到底能放什么数值,由上题可知,unsigned char类型取值范围是在0~255,当i++到255时,其二进制表示1字节为11111111,当i在加1的时候,11111111+1得到100000000,取8bit,再转换成10进制就是0,以此类推1,2,3,4,等等依次循环,所以会死循环打印hello world