数据在内存中的大小端存储 整型数据的存储和拿出方式 浮点型数据的存储和拿出方式。

1:大小端存储

我们知道数据在内存中都是有地址指向的,那么一个整形的数据到底是怎么存储的呢

我们打开内存监视窗口可以看到

二进制   00000000 00000000 00000000 10000000--->a

十六进制  00  00  00  80--->a      80被存储在低地址中,高位都是0,都存储在高地址中。

这种存储方式被称为   小端存储:

数据的高位存储在高地址中,数据的低位存储在低地址中。

与之对应的大端存储  :

数据的高位被存储在低地址中,低位被存储在高地址中。

2:在c语言中,有两大类型的数据

2.1:整形数据

1  char     2  short      3  int      4  long int

( char: 字符在内存中都是以ascll码进行储存,所以他是属于整形的范围。)

#include<stdio.h>
int main()
{
	int a = 128;
	char b = 1;
	int c = a + b;
	char d = a + b;
	printf(" %d\n", c);
	printf("%d\n", d);
	printf(" %u\n", d);
	return 0;
}

//运行结果
//129
//-127
//4294967169

int a=1;

系统会先生成: 00000000 00000000 00000000 10000000这样的一个二进制数

因为是一个正数,所以他的源码,反码,补码相同,而a是一个int类型的变量,也正好可以存下这32个比特位。

00000000 00000000 00000000 10000000--->a

int b=1;

系统会先生成: 00000000 00000000 00000000 00000001这样的一个二进制数

因为是一个正数,所以他的源码,反码,补码相同,

但是这里b的类型是一个char类型的变量,他里面只能存8个二进制位,所以这里会发生截断,最低的8个二进制位被放入了b中。

000000001   ---> b

int c=a+b;

寄存器在进行运算时,(寄存器的大小一般是int类型的大小)char  类型的b他只有8个位,这里就会发生整形提升,提升到32位,(如何提升在我之前博客有讲)

00000000 00000000 00000000 10000000--->a

00000000 00000000 00000000 00000001--->b

00000000 00000000 00000000 10000001--->c

c中放的就是   00000000 00000000 00000000 10000000;

后面以有符号整形的形式打印   “%d”,所以c打印出129.

char  d=a+b;

以有符号整型打印d

这里a和b在寄存器中的运算都是一样

00000000 00000000 00000000 10000000--->a

00000000 00000000 00000000 00000001--->b

00000000 00000000 00000000 10000001

但是因为d是char类型变量,所以会发生截断,b中存的是   10000001

他以有符号整形形式打印“%d”,因为他是char类型变量,这里又会进行整形提升。

而最高位的1,代表他是负数前面补符号位1,

(补码到源码,和源码到补码的方式相同)

11111111 11111111 11111111 10000001--->补码

10000000 00000000 00000000 01111110  ---

10000000 00000000 00000000 01111111--->源码(打印出来的数)

最高位1代表负数,最低7位表示127.

所以结果位-127.

以无符号整型打印d:

这里a和b在寄存器中的运算都是一样

00000000 00000000 00000000 10000000--->a

00000000 00000000 00000000 00000001--->b

00000000 00000000 00000000 10000001

但是因为d是char类型变量,所以会发生截断,b中存的是   10000001

他以整形形式打印d,因为他是char类型变量,这里又会进行整形提升。

而最高位的1,代表他是负数前面补符号位1,

(补码到源码,和源码到补码的方式相同)

11111111 11111111 11111111 10000001--->补码

10000000 00000000 00000000 01111110  ---

10000000 00000000 00000000 01111111--->源码(打印出来的数)

但是要注意这里是以%u来进行打印d,无符号整形在操作时没有符号位的概念,系统不会将最高位看成符号位,所以最后打印出了一个很大的数。

2.2:浮点型数据

他的存储方式是不是和整形的存储方式相同呢,下面我们通过一个示例来看一下

 从这个例子我们可以知道,整形和浮点型数据的存储,和取出方式都不相同。

浮点型数据的存储(只限c语言)

根据IE754标准,任何一个二进制浮点数  x 都可以表示成下面这种形式

(-1)^s*M*2^E,

这里的s  M  E 的作用形式如下:

(-1)^s   s表示符号位,s=0,表示正,s=1,表示负

M 表示有效数字(M必须满足的条件1<=M<2)

E 表示指数位

浮点数  5.5   十进制

            101.1  二进制   <=>(-1)^0*1.011*2^2,

               s=0  m=1.011 e=2

所以说,只要知道这三个值,就可以表示任何二进制下的浮点型数据

浮点型的32位二进制位中被分配给了  s(1个比特位)      e(8个比特位)    m(23个比特位)  

 这里详细说一个E 位的放置和M位的放置

1:E是一个size-t形式的数据,但是如果要将0.5放入一个float型数据的话

十进制  0.5         0.5<=>1*2^-1;

二进制  0.1(这个1的权重是2的-1次方)   

所以我们需要E是一个负值,但是定义里E是一个无符号数,所以在对E中数据进行存储时,会对它先加上一个127(float型) 或者1023(double),拿出的时候再减去。

2:M位置的放置

因为M必须大于等于1,小于2,所以在对M数据进行放置的时候,会将小数点前面的那个1不放入M的中,拿出的时候加上进行了。

知道这些我们就可以对开始的那个例子进行解释了

a=9

将9放入a中

00000000 00000000 00000000 00001001-->a

所以说a中存储的应该是这样的一串二进制码,但将其以float形式打印,s=0  e=00000000-127  (这里当e全为0时,拿出时e=1-127)=-126       m=00000000 00000000 1001 

所以,用float形式打印出的a要乘以应该2的负126次方,这个结果无线接近于0,而float小数位只有6位,所以打印出全0.

*pa=9.0

将9.0以float形式存入内存中

0(s位) 00000011(E位) 00100000000000000000(M位)

而将这个数以整形的形式打印,那么编译器就会用拿出整形数据的方式拿出这个数据,所以就会得到一个很大的数。

最后要注意一个点:

在上面整形的数据以浮点型数据打印的时候(或者浮点型数据以整形形式打印的时候)

一定要取地址然后进行强制类型转换,才能输出结果,不然只会输出0。

不然直接:

    printf("%f\n", b);
    printf("%d\n", a);

b是一个整形数据,也是以整形的形式拿出来的,但是却要以浮点型的类型进行输出,就会出错。

 对float类型变量的地址进行强制类型转换成int类型的地址后,打印时,才能对一个原本是以float类型存储方式的存储数据,才能以整形的形式打印。(同理int也是一样)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值