C语言整型在内存中的存储练习题详解1(Detailed explanation 1 of the practice questions of the storage in memory for c language )
C语言整型在内存中的存储 练习1 —— 说明以下代码输出结果
1 #define _CRT_SECURE_NO_WARNINGS 1
2 #include <stdio.h>
3
4 int main()
5 {
6 char a = -1;
7 signed char b = -1;
8 unsigned char c = -1;
9 printf("a=%d,b=%d,c=%d", a, b, c);
10 return 0;
11 }
对于这一道题,要关注几个点:
(1)-1原是32bit,但是强制把它存到了char —— 8bit中。
(2)在打印结果的时候,打印的是%d —— 整型,那就要算出每个变量整型的表示形式,所以这里需要进行整型提升(整型提升是按照这个数的原符号位来进行提升,而无符号数整型提升的时候最高位直接补0)。
代码详解:
(1)-1虽然要放入 char 中,但是 -1 的原码还是 32bit,我们先写出 -1 的原反补码:
-1 - 原码: 10000000 00000000 00000000 00000001 (最高位表示符号位是负数,此外部分表示1)
-1 - 反码: 11111111 11111111 11111111 11111110 (最高位不变,其他位按位取反)
-1 - 补码: 11111111 11111111 11111111 11111111 (反码+1)
因此,在内存中的 -1 就是 32 个全1的值,现在我们要把它放入 char 中,那就会取低 8 位放入 char 中,即无论是 char a 还是 signed char b 还是 unsigned char c ,当执行完 6,7,8 行命令的时候,a,b,c 内存中存储的都是 -1 的低八位 11111111(0xFF),这个可以通过在第 9 行打个断点,然后调试——窗口——内存 中,输入 &a,&b, &c 可以看出。如下图所示:
(2)当要使用整型打印 a,b,c 的时候,因为原类型是 char,而 char 类型要打印成整型的时候就要进行整型提升,即提升为整型才能打印整型。
a - 内存中存储的是 11111111 ,a 的类型是有符号的 char,所以在进行提升后,因为要按照这个数的原符号位进行提升,认为最高位即它的符号位,即1,所以提升后的 a 为 11111111 11111111 11111111 11111111
但是注意,提升之后的这个值是补码,我们想要知道它打印出来是多少,那就是要把它转换成原码,根据上面的计算,我们也知道提升之后的补码转换成原码后的值是 10000000 00000000 00000000 00000001,即 -1,所以 a 以整型 printf 出来的结果就是 -1
b - 同理 a,打印出来的结果也是 -1
c - 内存中存储的是 11111111,c 的类型是 unsigned char,它的最高位不是符号位,无符号位整型提升的时候高位直接补0,因此提升后的 c 为 00000000 00000000 00000000 11111111
但是注意,提升之后的这个值是补码,当要用 printf 进行打印的时候要的是原码,因此一看这个数的最高位 0,说明这个数是正数,而正数的原反补相同,所以原码也是 00000000 00000000 00000000 11111111 ,即 255
因此,运行代码的结果是: