C--数据在内存中的存储

本文详细解释了整数如何以二进制补码形式存储在内存中,包括大小端字节序的概念,以及不同进制之间的转换方法。同时介绍了浮点数的存储结构和处理规则,如S,M,E在浮点数表示中的作用。
摘要由CSDN通过智能技术生成

目录

一整数在内存中的存储

1.整数在计算机中如何存放的呢?

a.整数在计算机中是以二进制形式存放的。

b.那整数怎样转化为二进制?

1。数字系统的发展

2.位置化数字系统:

3.不同进制如何转换

a.10进制转化为2进制,8进制,16进制的方法:通过连除法(直到商为0),余数逆序排列。

b.2进制,8进制,16进制转化为10进制

c.二进制,八进制,十六进制转换

c.计算机存放整数的补码

总结一下:整数在计算机中是以补码的形式存放

二.大小端字节序

1.引入

2.什么是⼤⼩端?

3.为什么有大小端的区别

4.如何判断机器是大端模式还是小端模式?(百度笔试题:简述大小端,并且编写一个代码判断机器是大端还是小端)

总结:整数在内存中是以补码的形式按不同的机器选择对应的大小端模式存放数据。

三关于整数在内存中存放的练习题

1.练习一打印结果会是什么?

2.练习二打印结果会是什么呢?(%u无符号10进制整数)

3.练习三

4.还有一些练习咱们可以自己想想,随时保持交流呦~

三,浮点数(小数)在内存中的存储

1.浮点数(小数)(float,double,long double等)的二进制转换如图

2.S,M,E在浮点数的存储中有什么意义?

3.浮点数取的过程a.E全为0,此时1-127即为真实值(-1)^s*M*2^(1-127)近似为02.E全为1,此时如果M全为0,则表示±无穷大11111111==-128==E+127,则E=127+128=2553.E不全为0或1:正常算,不要忘记M+1,E-127。

4,浮点数在计算机存储时可能会有误差,建议abs(f1-f2)<预期差值。abs是求绝对值。

5.小练


一整数在内存中的存储

1.整数在计算机中如何存放的呢?

a.整数在计算机中是以二进制形式存放的。

b.那整数怎样转化为二进制?


1。数字系统的发展

由远古时期的划痕到非位置数字系统(罗马数字)最后到位置化数字系统(base 10,base 8,base 2,base 16)。

2.位置化数字系统:

a.10进制:由0,1,2,3,4,5,6,7,8,9共10个数字组成

b.2进制:由0,1两个数字组成

c.8进制:由0,1,2,3,4,5,6,7共8个数字组成

d,16进制:由0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F共16个数字组成

3.不同进制如何转换
a.10进制转化为2进制,8进制,16进制的方法:通过连除法(直到商为0),余数逆序排列

比如10进制80

80余数
2进制0000101
8进制021
16进制05

所以10进制80转化为二进制即为:1010000

10进制80转化为8进制即为:120

10进制80转化为16进制即为:50

b.2进制,8进制,16进制转化为10进制

比如上面1010000,120,50转化为10进制:

1010000: 0*2^0 + 0*2^1 + 0*2^2 + 0*2^3 + 1*2^4 + 0*2^5 + 1*2^6 = 80

120: 0*8^0 + 2*8^1 + 1*8^2 = 80

50: 0*16^0 + 5*16^1 = 80

是不是发现了一点规律,好像我们只需要用 对应进制数的次方(从0开始)* 每个数 然后相加就可以了。

c.二进制,八进制,十六进制转换

因为2^3=8,所以二进制中每三个数可以表示一位八进制数,同理因为2^4=16,所以二进制中每4个数可以表示一个16进制数。

比如1010000转化为八进制,过程如图

八进制,十六进制转化为二进制就逆过来,我们可以自己练习一下,在进制转换计算器上验证。


c.计算机存放整数的补码

i:整数的2进制表⽰⽅法有三种,即原码、反码和补码

ii:有符号整数的三种表⽰⽅法均有符号位和数值位两部分,2进制序列中,最⾼位的1位是被当做符号 位剩余的都是数值位。 符号位都是⽤0表⽰“正”,⽤1表⽰“负”。 正整数的原、反、补码都相同。整数的三种表⽰⽅法各不相同。

原码:直接将数值按照正负数的形式翻译成⼆进制得到的就是原码。

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

反码得到原码:取反,+1的操作。

补码:反码+1就得到补码。

总结一下:整数在计算机中是以补码的形式存放

二.大小端字节序

1.引入

int x = 0x11223344

//0x表示16进制

我们看一下它在内存中的存储方式,调试走起来

我们可以看到好像是倒着存储的?为什么?

因为该机器是按小端存储的

2.什么是⼤⼩端?

a.其实超过⼀个字节的数据在内存中存储的时候,就有存储顺序的问题,按照不同的存储顺序,我们分 为⼤端字节序存储和⼩端字节序存储.

b.⼤端(存储)模式:是指数据的低位字节内容保存在内存的⾼地址处,⽽数据的⾼位字节内容,保存 在内存的低地址处。

⼩端(存储)模式:是指数据的低位字节内容保存在内存的低地址处,⽽数据的⾼位字节内容,保存 在内存的⾼地址处。 

3.为什么有大小端的区别

这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着⼀个字节,⼀个字节为8 bit 位,但是在C语⾔中除了8 bit 的 char 之外,还有16 bit 的 short 型,32 bit 的 long 型(要看 具体的编译器),另外,对于位数⼤于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度⼤ 于⼀个字节,那么必然存在着⼀个如何将多个字节安排的问题。因此就导致了⼤端存储模式和⼩端存 储模式。

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

4.如何判断机器是大端模式还是小端模式?(百度笔试题:简述大小端,并且编写一个代码判断机器是大端还是小端)

法一:
#include <stdio.h>
int main()
{
	int x = 1;
	//0x 00 00 00 01
	if (*(char*)&x == 1)//&x==指针*p,char*强制类型转换,*解引用
		printf("小端");
	else
		printf("大端");
	return 0;
}//根据一个数据的判断就可以知道了
法二:写成函数的形式可以试试哦~

总结:整数在内存中是以补码的形式按不同的机器选择对应的大小端模式存放数据。

三关于整数在内存中存放的练习题

1.练习一打印结果会是什么?

#include <stdio.h>
int main()
{
 char a= -1;
 signed char b=-1;
 unsigned char c=-1;
 printf("a=%d,b=%d,c=%d",a,b,c);
 return 0;
}

分析:

a.char a = -1:-1是整数,因为int=4个字节=32个比特位,剩下的分析在图中

b.signed char和a分析差不多,关于char是有符号还是无符号,要看编译器,我用的是VS是有符号的

c.unsigned char,分析在图中

2.练习二打印结果会是什么呢?(%u无符号10进制整数)

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

分析如图

这是符号位不参与计算的结果

这是符号位参与计算的结果

3.练习三

#include <stdio.h>
int main()
{
 char a[1000];
 int i;
 for(i=0; i<1000; i++)
 {
 a[i] = -1-i;
 }
 printf("%d",strlen(a));
 return 0;
}

分析如图表示,而strlen计算的是字符串的长度,a[i]取值是-128~127,但是strlen遇到’0‘相当于遇到’\0',所以结果是128+127=255

4.还有一些练习咱们可以自己想想,随时保持交流呦~

1.
#include <stdio.h>
unsigned char i = 0;
int main()
{
 for(i = 0;i<=255;i++)
 {
 printf("hello world\n");
 }
 return 0;
}
2.
include <stdio.h>
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;
}
1

三,浮点数(小数)在内存中的存储

1.浮点数(小数)(float,double,long double等)的二进制转换如图

2.S,M,E在浮点数的存储中有什么意义?

a.

M:1<=M<2,所以M可以写成1.xxxxxxx的形式,IEEE 754规定,在计算机内部保存M时,默认整数1,可以舍弃,只保存后面小数部分。

比如1.01,只保存01
b.

E:无符号整数
E=8时取值范围是0~255
E=11时取值范围是0~2047
但是科学计数法中可以出现负数,因此IEEE754规定,存入内存时E的真实值必须再加上一个中间数127(或1023)

比如E=10,10+127=137,转化为二进制保存

3.浮点数取的过程
a.E全为0,此时1-127即为真实值
(-1)^s*M*2^(1-127)近似为0
2.E全为1,此时如果M全为0,则表示±无穷大
11111111==-128==E+127,则E=127+128=255
3.E不全为0或1:正常算,不要忘记M+1,E-127。

4,浮点数在计算机存储时可能会有误差,建议abs(f1-f2)<预期差值。abs是求绝对值。

5.小练

#include <stdio.h>
int main()
{
 int n = 9;
 float *pFloat = (float *)&n;
 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;
}

分析如图

还有一点没有分析,咱们可以自己分析试试,有任何疑问欢迎私信和评论

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值