首页 > 系统相关 >数据在内存中的存储<C语言>

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

时间:2024-06-03 23:58:03浏览次数:14  
标签:存储 字节 int 浮点数 补码 C语言 00000000 内存

导言

        在计算机中不同类型的数据在计算机内部存储形式各不相同,弄懂各种数据在计算机内部存储形式是有必要的,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,那么这个值就会无限的大,超出数据表示范围

标签:存储,字节,int,浮点数,补码,C语言,00000000,内存
From: https://blog.csdn.net/2302_80803681/article/details/139331700

相关文章

  • 成为MySQL DBA后,再看ORACLE数据库(六、逻辑存储结构)
    数据库的逻辑存储结构也可以叫做存储层次体系,ORACLE的存储层次体系按照层次从高到低分为:表空间(tablespace)、段(segment)、区(extent)、块(block)。熟悉数据库的逻辑存储结构可以帮助我们分析与定位数据库的空间容量问题。一、段段是表空间的主要组织结构。段就是占用存储空间的数据库......
  • 如何利用CXL技术突破内存墙?-1
    CXL诞生的基础是为了解决CPU内存和附加设备内存的互联,实现资源共享,得到最大的性能提升。随着数据大规模超算、AI、5G、云技术、边缘计算、自动驾驶等蓬勃发展,未来的数据存在指数级的增长且要求实时计算。从2019年的CXL1.0,CXL协议目前已经发展了CXL3.1。服务器目前正面临着......
  • 如何利用CXL技术突破内存墙?-2
    为了解决这些问题,业界正积极寻求新的技术和标准,比如ComputeExpressLink(CXL),它旨在通过提供标准化的高速互连来提高内存带宽、降低延迟,并简化内存扩展的软件集成,从而有效地打破内存墙的限制。通过使用CXL(ComputeExpressLink)技术来突破内存墙,可以实现以下几项关键改进,比如......
  • 杨辉三角C语言的超简单解决办法
    #include<stdio.h>#include<stdlib.h>intmain(){intarr[10][10]={0};//十行的杨辉三角intsize=sizeof(arr)/sizeof(arr[0]);//求一共有几行for(inti=0;i<size;i++){for(intj=0;j<=i;j++)//对角线{if(i==j||j=......
  • 浙大翁恺《C语言程序设计》课程笔记
    1.1计算机与编程语言设计算法->编写程序->计算机执行程序执行的两种方式1.解释:借助一个程序(解释器),那个程序能试图理解你的程序,然后按照你的要求让计算机执行2.编译:借助一个程序(编译器),把你的程序翻译成机器语言,然后让计算机执行编程语言本身没有解释型和编译型之......
  • 如何在 Hive 中存储类列表?
    我有一个通过模型类从api获取的itemlist,现在我想将该列表保存到hive中,并添加一些其他属性,如客户名称、客户地址和itemsList。import'package:hive/hive.dart';导入'.../item_model.dart';导入'hive_model.dart';part'saved_hive_model.g.dart';@HiveType(typeId:15)......
  • C语言程序设计第二讲:顺序程序设计
    一、数据类型1.基本数据类型C语言中提供了一些基本数据类型,用于表示各种不同类型的数据:整数类型:int:表示整数,通常占用4个字节。shortint:表示短整数,通常占用2个字节。longint:表示长整数,通常占用4或8个字节。longlongint:表示更长的整数,通常占用8个字节。unsignedi......
  • c语言中,结构体变量交换改写为堆空间申请内存
            在这里我实现的功能为:输入三个人的信息,每个人的信息分别为姓名和三个成绩,我分别计算三个人的成绩和,并通过经典的三杯水案例完成对三个人的成绩从小到大的排列打印。重点:     我这里使用的为堆空间申请内存的形式 第一步:        定义一个......
  • 初识C语言(02)—学习笔记
    转义字符转义字符释义\0结束标志\n换行\'打印单引号\"打印双引号\\打印一个反斜杠\t水平制表符\a警告字符,蜂鸣?在书写连续多个问号时使用,防止它们被解析成三字符\dddddd表示1~3个八进制的数字\xdddd表示2个十六进制数字\v垂直......
  • 在MySQL中,你可以使用动态SQL和存储过程来根据元数据表查询多个表,并将结果集合并。以下
    DELIMITER$$CREATEPROCEDUREMergeDataFromTables()BEGIN--游标声明DECLAREdoneINTDEFAULTFALSE;DECLAREtbl_nameVARCHAR(255);DECLAREcurCURSORFORSELECT表明FROMtable_col;DECLARECONTINUEHANDLERFORNOTFOUNDSETdone=TRU......