2026/1/10 13:52:05
网站建设
项目流程
国家有规定必须做可信网站验证,网站建设对企业很重要,建设招标网 官方网站,恶意 镜像网站前言#xff1a;在c语言中存在很多数据类型#xff0c;它们在内存中的存储是存在不同的特性的#xff0c;了解这个章节对深入了解c语言很有帮助。 1.整数在内存中的存储方式
整数在内存中有三种存储方式分别为#xff1a;原码、反码、补码
如果数据的类型是有符号整数在c语言中存在很多数据类型它们在内存中的存储是存在不同的特性的了解这个章节对深入了解c语言很有帮助。1.整数在内存中的存储方式整数在内存中有三种存储方式分别为原码、反码、补码如果数据的类型是有符号整数signed那数据在内存中的原码最高位为符号位其中0表示正数1来表示负数如果是无符号整数unsigned int时那4个字节的大小是数值位这就是为什么无符号类型的整数比有符号整数可以表示更大的绝对值。正整数的原码、补码、反码都是相同的而负整数的原码、反码、补码各不相同下面是具体方式来源于百度1原码是一种计算机中对数字的二进制定点表示方法。原码表示法在数值前面增加了一位符号位即最高位为符号位正数该位为0负数该位为10有两种表示0和-0其余位表示数值的大小。2反码是计算机编码系统中用于表示有符号数的二进制编码方法与原码、补码共同构成三种基本表示法。其编码规则为正数的反码与原码一致负数的反码保持符号位不变数值位按位取反3补码反码1得到补码在内存中不管是计算还是存储都是以补码的形式来进行的因为补码和原码在计算机中可以互相转化不需要额外的电路我这里就不展开来讲了。2.大小端字节序这里我同个一串简单的代码来解释大小端字节序我用的编译器是vs所以用vs小端字节序来演示int main() { int a 0x11223344; return 0; }打开vs的调试这时我们会发现位数低的数组在低地址上存放而高位数在高地址处存放。这里就引出了我们大小端字节序的概念在前面关于指针的文章中我曾经介绍过内存分为一个个的内存单元而一个内存单元能够存放的大小为一个字节所以当我们要存储的数据大小超过一个字节比如一个整形的大小为四个字节时就会涉及到字节存储顺序的问题所以根据存储顺序的不同分为两种模式1大端字节序模式大端字节序将高位字节存储在低地址处低位字节存储在高地址处2小端字节序模式小端字节序则与大端字节序相反低位字节存储在低地址处2.1字节序的代码判断通过编译器的调试模式我们可以轻而易举的判断大小端字节排序我们同样也可以通过代码来进行判断int main() { int a 1; if (*(char*)a 1) { printf(小端\n); } else printf(大端\n); return 0; }运行程序可以看到程序符号我们的预期成功判断了字节序为小端模式原理也非常简单通过取出整形变量a的地址并强转为了char*类型这样我们通过*来访问时就会访问第一个低地址字节的空间因为整形变量a在内存中以二进制的形式存储时低位为1这样我们就成功的证明了低地址存放的是低位上的数据所以为小端字节序模式。3.浮点数在内存中的存储浮点数在内存中的存储不同于整数它有着单独的存储方式这里我们同样通过一串代码来引出int main() { int n 9; float* pFloat (float*)n;//int* printf(n的值为%d\n, n); printf(*pFloat的值为%f\n, *pFloat); *pFloat 9.0; printf(num的值为%d\n, n); printf(*pFloat的值为%f\n, *pFloat); return 0; }运行结果为可以看到上第二低三行都输出了比较反直觉的数字这又是什么原因呢这是因为浮点数在计算机中有专门的表示方法有着一个统一的标准IEEE754参考文献链接维基百科介绍浮点数在内存中的存储正是以这个公式为标准的具体这么存下面我会慢慢介绍。我举一个例子来方便大家理解这个公式。就以十进制的5.0来说写成二进制的话就是101.0在这个公式中表示为-1^0×1.01×2^2因为该数为正数所以符号位s 0而101.0在二进制中可以写成1.01×2^2 其中1.01是有效数字M而后面的2E2^2表示的是指数位另外这个标准还规定了浮点数在内存的存储方式对于32位的浮点数来说最高位sign用一个位的空间来存放符号位来表示正负接下来的八个位exponent来存放指数E剩下的23位用于存储有效数字M。对于64位大小的浮点数也是一样的只不过用于存放指数位E的大小变为11位M变为52位。这也是为什么64位双精度浮点数的存储精度更高的原因。浮点数存储的过程细节前面也介绍过M的取值范围是1~2不包含2M在保存时只保存小数部分比如1.012就只会保存012等需要读取时再加上一个1这样做可以使得原本只能存放23位有效数字的M可以存放24位有效数字。而指数E的存储则相对于M来说比较复杂E是一个无符号的整数unsigned int但是我们的科学计数法是可以出现负数的为了处理这个问题IEEE 754规定了当E为8位时需要加上127这个中间值来表示负数而对于11位的E来说就需要加上10233.1浮点数取的过程浮点数在取出的时候分为三种情况1E不全为0或者不全为1这个一样的情况下只需要把有效数字M加上一个1然后再减去E的中间值就可以了2E全为1但有效数字全为0时会表示一个无穷大的数组正负取决于符号位3E全为0这个时候E减去中间值就是它的真实值了不用对M加1用于表示接近0很小很小的数组正负同样取决于符号位。这个时候我们就可以解答一开始的那行代码了再第二行中为什么9被打印出来就成了0.00……呢将9转化为二进制为0 00000000 00100000000000000000000满足了E全部为0时的特殊情况不再对M加1指数部分再减去中间值所以此时的9时个很小很小非常接近与0的数字。同样有了上面的知识就可以解答为什么9.0以整数的形式打印的时候会出现一个很大的数字了9.0在内存中的存储方式为(−1)^0 ∗ (1.001) ∗ 2^3写成以浮点数的存放形式就为0 10000010 001 0000 0000 0000 0000 0000因为正整数的原码、反码、补码都相同所以当以整形的方式来打印时正是1091567616完