C语言必备知识点1 —— 数据在内存中的存储(Essential knowledge point 1 for C - storage of data in memory)
最近在B站上系统地学习C语言,看了比特鹏哥的视频,确实有醍醐灌顶之感,看到了进阶阶段,开始学习《C语言数据的存储》这一部分内容,觉得这些内容虽然不起眼,但是对于对C语言的理解,已经数据的存储以及调试有极大的帮助,我认为用C语言进行编程的人员必须要明白这些细节,所以写下来分享给大家~
这部分讲解的内容主要是理解C语言中 —— 原码、反码、补码
在明白原码、反码、补码之前大家要明白这些概念只针对 整数,也就是说浮点数家族(float 和 double)在内存中的存储不是用原反补码这一套规律来存储的。
1. 一个变量的创建时要在内存中开辟空间的,空间的大小时根据不同的类型决定的。这时候,就涉及到了 ”C语言数据在内存中的存储“ 这一部分的内容。
2. C语言中整型家族包括哪些数据类型?
char - 字符型,认为是整型是因为字符传到内存中是用ASCII值存储 - 8bit
unsigned char
signed char
short - 短整型 - 16bit
unsigned short [int]
signed short [int]
int - 整型 - 32bit
unsigned int
signed int
long - 长整型 - 64bit
unsigned long [int]
signed long [int]
3. 原码、反码、补码
对于正数数据来说,数据存放在内存中其实存放的是补码。(至于为什么,老师有举了例子说了用补码能更好的进行加减法运算等原因)
(1)正数:原码、反码、补码相同
(2)无符号数:原码、反码、补码相同
(3)负数
- 原码:把数翻译成二进制得到的就是原码,这时候最高位表示符号位,符号位为1表示负数,符号位为0表示正数。printf 打印出来看到的就是原码,即调试模式下监视窗口看到的就是原码。
- 反码:符号位不变,数值位(除了最高位以外的位就叫数值位)取反。
- 补码:反码 + 1 . 补码就是数据在内存中存放的真正的形式,在调试模式下内存窗口显示的就是补码。当C语言顶层进行数据运算的时候用的也是补码。
4. 原码、反码、补码举例
当在C语言中写出了:
int a = 21;
int b = -19;
这个命令的时候,代码执行时就会在内存中开辟4个字节的空间(因为 int 类型占了4个字节)
我们先写出 21 的原反补码:
int 21 原码 - 直接把十进制转换成二进制,因为 int 类型占32个bit位,所以高位要填充0至32个位:
00000000 00000000 00000000 00010101
int 21 反码 - 因为是正数,所以反码和原码相同:
00000000 00000000 00000000 00010101
int 21 补码 - 因为是正数,所以补码和原码相同:
00000000 00000000 00000000 00010101 - 转换成十六进制就是 00000015
接下来我们再写出 -19 的原反补码:
int -19 原码 - 直接把十进制转换成二进制,因为 int 类型占32个bit位,所以高位除了符号位之外的要填充0至31个,因为是负数,所以符号位是1:
10000000 00000000 00000000 00010011
int -19 反码 - 符号位不变,其他位按位取反:
11111111 11111111 11111111 11101100
int -19 补码 - 反码+1:
11111111 11111111 11111111 11101101 - 转换成十六进制就是 FFFFFFED
接下来调试看结果:
输入代码:
1 #define _CRT_SECURE_NO_WARNINGS 1
2 #include <stdio.h>
3
4 int main() {
5 int a = 21;
6 int b = -19;
7 printf("a = %d \n", a);
8 printf("b = %d \n", b);
9 return 0;
10 }
首先,运行程序,可以看到控制台输出的是:
即控制台输出的是原码。
其次,在第7行打上断点,再运行程序进入调试模式, 点击 调试—— 窗口 —— 内存 —— 内存1,就可以看到打开了内存窗口,这时候输入 &a 获取 a 的地址,就可以看到如下内容:
再输入 &b 就可以看到如下内容:
把图中的结果和上面计算出来的反码的十六进制进行比对,可以看出一摸一样,由此可以看出,内存中存储的是反码。(至于低地址在前,高地址在后,这个涉及到大小端存储模式, 这里用的是小端存储——低位存储低地址,高位存储高地址)
补充知识:
我们经常听一句:计算机内部是用二进制存储的,那怎么理解呢?
鹏哥解释道:电脑是硬件 —— 硬件是需要通电的 —— 通电后有正电/负电之分,在计算机中,正电用1,负电用0表示,计算机能够处理的就是电信号,就是0和1这样的信号。