数据在内存中的存储<C语言>

导言

        在计算机中不同类型的数据在计算机内部存储形式各不相同,弄懂各种数据在计算机内部存储形式是有必要的,C语言的学习不能浮于表面,更要锻炼我们的“内功”,将来在写程序的时候遇见各种稀奇古怪的bug时,也便能迎刃而解,所以本文将着重介绍,整数在内存中的存储、大小端字节序和判断、浮点数的存储。


整数在内存中的存储

       这部分的内容在前面已经讲过,现在让我们来复习一下:

一个数的二进制表示方法有三种:原码、反码、补码

        原码:直接将数转为2进制序列,得到的就是原码

        反码:符号位不变,将其它位取反

        补码:在反码基础上+1

在C语言中整数可分为有符号整数和无符号整数

        有符号整数:有符号位(第一位),0为正、1为负

        有符号整数:没有符号位,即全为正数。

在计算机内部存放的是补码,为啥是补码?

        因为CPU只有加法器,在计算机内部,正数的补码是本身,负数补码符号位不变,其他位取反,存放补码可实现加减法的统一运算(不需要添加减法器):

//在计算机内部存放的是补码,为啥是补码?
int main() {
	int a = 9;
	//a的补码:00000000 00000000 00000000 00001001
	int b = 4;
	//b的补码:00000000 00000000 00000000 00000100
	int c = a - b;
	//c=a-b会被转化为c=a+(-b)
	// a的补码:00000000 00000000 00000000 00001001
	//-b的补码:11111111 11111111 11111111 11111100
	// c的补码 100000000 00000000 00000000 00000101
	//相加结果多出一位,int型只有4字节、32位,高位抛弃
	// c的补码: 00000000 00000000 00000000 00000101
	//正数原反补相同,10进制数为5
	printf("%d", c);
	return 0;
}

运行结果:


 大小端字节序和判断

        超过一个字节的数据在存储时就会有存储顺序的问题:

         通过调试观察一个整型在内存中的存储可知:a的低位存储在低地址处,当前平台属于小端存储模式。

大端存储模式:

        是指数据的低位字节存储在内存空间的高位地址处。(大对大)

小端存储模式:

        是指数据的低位字节存储在内存空间的低位地址处。(小对小)

为了更好的理解下面给出几道练习:

        练习1(百度笔试10分)

简述大端字节序和小端字节序的概念,设计一个程序来判断当前机器的字节序。

        

         练习2

以下代码输出结果是啥?

#include <stdio.h>
//X86环境 ⼩端字节序 
int main()
{
	int a[4] = { 1, 2, 3, 4 };
	int* ptr1 = (int*)(&a + 1);
	int* ptr2 = (int*)((int)a + 1);
	printf("%x,%x", ptr1[-1], *ptr2);
	return 0;
}

运行结果:

 分析一下:

#include <stdio.h>
//X86环境 ⼩端字节序 
int main()
{
	int a[4] = { 1, 2, 3, 4 };
	int* ptr1 = (int*)(&a + 1);
    //&a取出整个整个数组的地址(访问权限为4*sizeof(int)个字节),再加1到元素4的后面
	int* ptr2 = (int*)((int)a + 1);
    //(int)a:将地址转为int类型的数,并加1,就是加了一个字节
    //因为当前平台为小端字节序,加1跳过了01,并从第二个字节开始00 00 00 02
	printf("%x,%x", ptr1[-1], *ptr2);
    //ptr[-1],访问权限为int型,倒退4字节,来到4的起始地址并打印
    //*ptr2:00 00 00 02,因为平台为小端字节序,所以该数为2000000
	return 0;
}

浮点数的存储

        浮点数的存储是比较特殊的,因为它具有小数位,如果采用整数存储方法肯定是不行的,于是IEEE(国际电气和电子工程协会)754规定,任意一个浮点数V可以表示为下面这种形式:

●-1的S次方:符号位,S为1时负数,S为0时正数

●M:有效数字,M大于1小于2

●E:指数位

如10进制数5.5转为二进制数101.1

那么S=1

        M=1.011

        E=2

浮点数在存储时就是存储的SME,值得注意的是,常见浮点数float和double型的字节长度是不一样的,那么在存储时,SME的内存分配会有所不同:

注意点:

●前⾯说过, 1≤M,也就是说,M可以写成 1.xxxxxx 的形式,其中 xxxxxx 表⽰⼩数部分。 因此1.可以舍去。

●指数E,E为一个无符号整数,为了能存负数,754规定:存入内存时E的真实值必须再加上一个中间数,float:127,double:1023

举例:

#include <stdio.h>
int main()
{
	int n = 9;
	//小端字节序:00001001 00000000 00000000 00000000
	float* pFloat = (float*)&n;
	//转为float,但是存储的数据没有发生变化,依旧是00001001 00000000 00000000 00000000
	printf("n的值为:%d\n", n);//9
	printf("*pFloat的值为:%f\n", *pFloat);//0.000000
	//以%f的形式打印,那么会把这个数据float的方式读取,也就是SEM的形式
	//0 0001001 000000000000000000000000=1.0*2的(9-127)次方,无限接近于0
	*pFloat = 9.0;
	//以浮点数存储也就是0 10000010 00100000000000000000000
	printf("num的值为:%d\n", n);
	//将0 10000010 00100000000000000000000以整数形式读取也就是1,091,567,616
	printf("*pFloat的值为:%f\n", *pFloat);
	//9.000000
	return 0;
}

运行结果:

 值得注意的是在浮点数存储的时候,E有几种特殊情况:

●E全为0时,还原成2进制数时,还要减去中间数,那么这个值就会无限的小(并且M不会加上省略的1),接近于0,超出数据表示范围

●E全为1时,还原成2进制数时,255减去中间数,指数E为255,那么这个值就会无限的大,超出数据表示范围

相关推荐

  1. C语言L / 数据内存存储

    2024-06-06 05:30:02       44 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-06 05:30:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-06 05:30:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-06-06 05:30:02       82 阅读
  4. Python语言-面向对象

    2024-06-06 05:30:02       91 阅读

热门阅读

  1. AWK使用总结

    2024-06-06 05:30:02       28 阅读
  2. 鲁教版八年级数学上册-笔记

    2024-06-06 05:30:02       31 阅读
  3. 有多少苹果用来分赃

    2024-06-06 05:30:02       26 阅读
  4. 枚举类型知识点

    2024-06-06 05:30:02       32 阅读
  5. Linux中挂载Windows Samba共享的指南

    2024-06-06 05:30:02       30 阅读
  6. python基于百度,哈工大等停用表进行的中文分词

    2024-06-06 05:30:02       25 阅读
  7. 个人关于ChatGPT的用法及建议

    2024-06-06 05:30:02       31 阅读
  8. 【Linux】将U盘中的程序更新到开发板中 shell 脚本

    2024-06-06 05:30:02       29 阅读
  9. HCIA-HarmonyOS Device Developer 课程大纲

    2024-06-06 05:30:02       33 阅读
  10. Homebrew、RVM、ruby、cocoapods

    2024-06-06 05:30:02       38 阅读
  11. actuator/env;.js 漏洞修复

    2024-06-06 05:30:02       36 阅读