【C语言基础——计算机数据存储】
目录一、大小端字节序1.大小端字节序2.大小端存储模式的原因2.字节序判断二、数据在内存中的存储1.整数内存中的存储1整数的存储形式2有符号整数和无符号整数的范围a.有符号数b.无符号数2.浮点数在内存中的存储1整数和浮点数表示的不同2二进制浮点数的表示3.浮点数的取出1.E不全为0或不全为12.E全为03.E全为1一、大小端字节序1.大小端字节序大小端超过一个字节的数据在内存中存储时存在的字节存储顺序的问题大端字节序存储高位字节存储在低地址低位字节存储在高地址小端字节序存储低位字节存储在低地址高位字节存储在高地址下面以32位整数0x11223344为例#includestdio.hintmain(){intn0x11223344;return0;}调试从调试截图可以看到内存中显示为44 33 22 11表明当前VS采用的是小端字节序存储2.大小端存储模式的原因计算机系统中以字节为最小寻址单位每个地址对应1个字节。在C语言中除了8bit的char类型以外还有许多不同字节大小的类型当处理16位、32位、64位等多字节数据时不同处理器架构选择了不同的字节排列方式由此诞生了大端和小端两种存储方式大端符合人类阅读习惯常用于网络传输、嵌入式设备小端更利于CPU计算x86架构的PC大多采用小端2.字节序判断判断当前机器字节序思路取出1的地址强转为char*然后解引用即得到第一个字节的内容#includestdio.hintmain(){intn1;if(*(char*)n1)printf(小端\n);elseprintf(大端\n);return0;}运行结果二、数据在内存中的存储1.整数内存中的存储1整数的存储形式整数的取值范围定义limits.h数据在内存中以二进制补码的形式存储表示方式有原码、反码、补码内存中存储的是补码正整数的原反补码相同负整数三中表示方法各不相同详见2有符号整数和无符号整数的范围以char类型为例其它整数类型的取值范围定义在limits.h这个头文件中a.有符号数b.无符号数2.浮点数在内存中的存储1整数和浮点数表示的不同浮点数有多种表现方式有常见的3.14159也有科学计数法表示1E6浮点数表示的范围定义float.h整数和浮点数在内存中的编码规则完全不同直接用一种类型读取另一种类型会得到完全不同的结果#includestdio.hintmain(){intn9;float*pf(float*)n;printf(n的值为%d\n,n);printf(*pf的值为%f\n,*pf);//整数9的二进制被当作浮点数解析*pf9.0f;printf(n的值为%d\n,n);//浮点数9的二进制被当作整数解析printf(*pf的值为%f\n,*pf);return0;}运行结果这表明整数和浮点数的二进制编码规则完全不同不能直接混用2二进制浮点数的表示根据国际标准IEEE电气和电子工程协会754任意一个二进制浮点数可以表示成以下形式:V ( − 1 ) S ∗ M ∗ 2 E V(-1)^S* M* 2^EV(−1)S∗M∗2E( − 1 ) S (-1)^S(−1)S表示符号位当S等于0V为正数当S等于1V为负数M表示有效数字1 ≤ M 2 1 \le M 21≤M22 E 2^E2E表示指数位浮点数的存储其实存的就是S、M、E相关的值IEEE 754规定float32位浮点数最高的1位存储符号位S接着的8位存储指数E剩下的32位存储有效数字Mdouble64位浮点数最高的1位存储符号位S接着的11位存储指数E剩下的52位存储有效数字MMIEEE 754规定在计算机内部保存M时默认第一位总是1因此可以舍去只保存后面部分。这样的做法可以节省一位有效数字EE为一个无符号整数因此当E为8位时它的取值范围是0~255当E是11位时它的取值范围是0~2047。由于科学计数法中E有时为负数因此IEEE规定存入内存时E的真实值必须再加上一个中间数8位的E中间数为12711位的E中间数为1023Tips由于存储的位数有限因此如果小数点后的位数太多有可能导致浮点数在内存中无法精确保存3.浮点数的取出浮点数的取出以指数E的不同值分为3种情况1.E不全为0或不全为1真实指数存储的E值-偏移量127或1023有效数字M1.存储的小数部分2.E全为0真实指数1-偏移量有效数字M0.存储的小数部分表示接近0的极小值3.E全为1若M全为0表示±无穷大符号由S决定若M不全为0表示NaNNot a Number非数值