C语言中数据如何存储进内存揭秘_第1页
C语言中数据如何存储进内存揭秘_第2页
C语言中数据如何存储进内存揭秘_第3页
C语言中数据如何存储进内存揭秘_第4页
C语言中数据如何存储进内存揭秘_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第C语言中数据如何存储进内存揭秘目录内存简单介绍整数与字符在内存中的存储浮点数在内存中的存储大小端存储模式及简介总结

内存简单介绍

大家肯定经常听说内存这个词,内存到底是什么呢?在计算机中,进程都要加载进内存中,也是我们各种数据的流通途径,C语言中,大家肯定都知道指针变量,指针变量中保存的就是内存的地址,那么,什么是内存的地址呢?

内存的单位是字节

对于32位的机器,有32根地址线,每根地址线在寻址时,产生的高低电压分别为0/1,那么32根地址线产生的地址就会是

00000000000000000000000000000000

00000000000000000000000000000001

00000000000000000000000000000010

11111111111111111111111111111111

这里就有2^32次方个地址

大家应该知道,还有64位的机器,64根地址线又有多少个地址呢,大家可以计算一下

在32位的机器上,地址是32个0或者1组成二进制序列,那地址就得用4个字节的空间来存储,

所以一个指针变量的大小就应该是4个字节。那如果在64位机器上,有64个地址线,那一个指针变量的大小是8个字节,才能存放一个地址。

这串编号就是内存单元的地址,就像酒店的房间号一样,对应着内存中的一个字节大小的房间

我们在vs中来看一下

这里是以十六进制的方式展示的,大家也知道,32个数字看起来太长了。

整数与字符在内存中的存储

关于c语言中的数据类型,大家在写了这么多代码后肯定也很清楚了,C语言中有整型、浮点型、字符型、等等

我们来研究一下整数在内存中是如何存储的

大家都知道,定义变量,会在内存中开辟空间来存储

inta=20;

int类型在vs中占据4个字节的空间,那么如何存储呢?

这就涉及到原码反码补码的概念

计算机中的整数有三种2进制表示方法,即原码、反码和补码。三种表示方法均有符号位和数值位两部分,符号位都是用0表示正,用1表示负,剩下数值位正数的原、反、补码都相同。负整数的三种表示方法各不相同。

原码:

直接将数值按照正负数的形式翻译成二进制就可以得到原码

反码:

将原码的符号位不变,其他位依次按位取反就可以得到反码

补码:

反码+1就得到补码。

对于整型变量来说,内存中存放的其实是补码

使用补码,可以将符号位和数值域统一处理,加法和减法也可以同一处理,因为CPU只有加法器

eg:

inta=20;

//原码:直接写二进制00000000000000000000000000010100

//反码--补码--正数的原反补相同

intb=-5;

//原码:10000000000000000000000000000101

//反码:符号位不变,按位取反

//11111111111111111111111111111010

//补码:反码+1

//11111111111111111111111111111011---5的补码

上边可以看见-5的补码是11111111111111111111111111111011,我们如何确认呢?

转换成16进制为fffffffb

大家可以看到确实是使用补码存储的,但是为什么是倒着存储的,后边再来说,这是由于大小端的问题

给大家举几个例子,不知道存储无法分析出结果代码

//1.

#includestdio.h

intmain()

chara=-128;

printf("%u\n",a);

//-128原码:10000000000000000000000010000000

//-128反码:11111111111111111111111101111111

//-128补码:11111111111111111111111110000000

//存在a里面的,因为只有一个字节10000000

//所以会当做无符号整数打印--整形提升

//提升为11111111111111111111111110000000

//所以结果是一个很大的整数,大家可以尝试一下

return0;

}

#includestdio.h

intmain()

chara=128;

//128的原码反码补码:00000000000000000000000010000000

//存在a里的:10000000

//整形提升:11111111111111111111111110000000

//所以结果还是那个很大的整数

printf("%u\n",a);

return0;

例子就简单给大家举到这里,大家一定要记住整数在内存中是以补码的形式存储的

字符存储的是ASCII码,所以和整数同

浮点数在内存中的存储

我们来看一下浮点数在内存中的存储

抛砖引玉:

#includestdio.h

intmain()

intn=9;

float*pFloat=(float*)

printf("n的值为:%d\n",n);

printf("*pFloat的值为:%f\n",*pFloat);

*pFloat=9.0;

printf("num的值为:%d\n",n);

printf("*pFloat的值为:%f\n",*pFloat);

return0;

上面代码的打印结果到底是什么呢?

是不是非常出乎大家的意料呢,这里就可以看出,浮点数的存储肯定和整数是不同的。那浮点数到底咋存的呢?

根据国际标准IEEE(电气和电子工程协会)754,任意一个二进制浮点数V可以表示成下面的形式:

(-1)^S*M*2^E(-1)^S表示符号位,当S=0,V为正数;当S=1,V为负数。M表示有效数字,大于等于1,小于2。2^E表示指数位。

看得很迷糊,直接上例子

v=5.5

=101.1--二进制表示

=1.011*2^2科学记数法表示

因为是正数s=0

m=1.011

e=2

IEEE754规定:

对于32位的浮点数,最高的1位是符号位s,接着的8位是指数E,剩下的23位为有效数字M。

IEEE754对有效数字M和指数E,还有一些特别规定

1=M2,所以M可以写成1.xxxxx所以可以舍去1,只存储xxxxxx

IEEE754规定,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的xxxxxx部分。比如保存1.01的时候,只保存01,等到读取的时候,再把第一位的1加上去。这样做的目的,是节省1位有效数字。以32位浮点数为例,留给M只有23位,将第一位的1舍去以后,等于可以保存24位有效数字

对于指数E,E是一个无符号整数,但是科学记数法指数是可以出现负数的,所以

IEEE754规定了偏移量,如果E为8位,则加上127,如果E为11位,则加上1023

我们举个例子

floatf=8.5f;

//二进制:1001.1

//科学计数法表示:1.0011*2^3

//S=0M=1.0011E=3

//存储进去的应该是:

01000001000110000000000000000000

//我们可以验证一下

转换成16进制

01000001000110000000000000000000

//41180000

我们来看一下代码

和我们想的一样

我们再来举一个负数的例子

floatt=-3.5f;

//二进制:11.1

//科学记数法:1.11*2^1

//S=1M=1.11E=1

//存储:

11000000011000000000000000000000

//转换成16进制

11000000001100000000000000000000

c0600000

那我们从内存中读取出来的二进制位如何解析成浮点数呢

关于E,有三种情况

E不全为0或不全为1

这时,浮点数就采用下面的规则表示,即指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第一位的1

2.E全为0

这时,浮点数的指数E等于1-127(或者1-1023)即为真实值,

有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数。这样做是为了表示0,以及接近于0的很小的数字。

3.E全为1

这时,如果有效数字M全为0,表示无穷大(正负取决于符号位s);

我们来分析一下最开始的题目

浮点数和整数的存储就介绍到这里了,有哪里不清楚的朋友可以私信我

大小端存储模式及简介

上边有一个悬念,为什么是倒序存储的

那什么是大端小端呢?

大端(存储)模式:数据的低位存储在内存的高地址中,数据的高位存储在内存的低地址中

小端(存储)模式:数据的低位存储在内存的低地址中,数据的高位存储在内存的高地址中

那为什么会有大小端呢?

内存中以字节为单位,但是比如int是4个字节,那如何安排这个4个字节呢?就导致了大小端存储模式

例如:一个16bit的short型x,在内存中的地址为0x0010,x的值为0x1122,那么0x11为高字节,0x22为低字节。对于大端模式,就将0x11放在低地址中,即0x0010中,0x22放在高地址中,即0x0011中。小端模式,刚好相反。我们常用的X86结构是小端模式,而KEILC51则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。

那我们如何测试当前电脑是哪种存储模式呢?

intmain(void)

inta=0x11223344;

return0;

}

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论