【C语言】整型和浮点型在内存中如何存储

文章目录

  • 一、整型在内存中的存储
    • 1. 原码、反码、补码
    • 2. 大端存储和小端存储
  • 二、浮点型在内存中的存储

一、整型在内存中的存储

一个变量的创建是要在内存中开辟空间的,而空间的大小是根据变量的类型决定的。
那么,开辟了空间之后,数据又是如何存储的呢?
对于整型来说,我们需要先了解下面的几个概念:

1. 原码、反码、补码

计算机中的整数有三种二进制表示方法:原码、反码和补码。

  • 原码:将整数直接翻译成二进制
  • 反码:原码的符号位不变,其他位按位取反
  • 补码:反码 + 1

因为整数在内存中是以补码形式存储的,所以所有对整数的运算都是对补码进行运算

因此,想要搞清楚整数的运算,就得明白原、反、补码三者的转换关系:

  • 从原码到补码:符号位不变,按位取反,再加1。
  • 那么倒过来,补码到原码只需要先减1,再按位取反。
  • 其实,补码到原码也可以先按位取反,再加1。
    【C语言】整型和浮点型在内存中如何存储_第1张图片

结论:

  • 原码 -> 反码:符号位不变,其他位按位取反
  • 原码 <-> 补码:符号位不变,按位取反再加1

规定:

  • 正数的原、反、补码都相同
  • 负数的原、反、补码各不相同

来看个例子:

【C语言】整型和浮点型在内存中如何存储_第2张图片先将十进制数字转换为二进制原码。
注意到-128是负数,原反补码各不相同,需要得到补码,所以符号位不变,取反加1。
将-128赋给i,由于char只占8个字节,故进行截断。
打印整数,要进行整型提升,i是有符号类型,左边用符号位补。
以%u打印,无符号整型,原码就是补码,所以直接将补码转换成十进制即可。

再来看一个
【C语言】整型和浮点型在内存中如何存储_第3张图片
128是正数,原反补相同,直接转换成二进制,就是补码。
赋给a,截断。
打印整数,进行整型提升,a是有符号类型,用符号位补。
以%u打印,无符号整型,原码就是补码,直接转换为十进制即可。

再来看
【C语言】整型和浮点型在内存中如何存储_第4张图片
-20是负数,先写出原码,再符号位不变,取反加1,得到补码,赋给b。
10是正数,原码就是补码,直接写出二进制补码,赋给c。
以%d形式打印b+c,%d有符号整数,有符号位。
符号位为1,是负数,补码要转换成原码,符号位不变,取反+1。
原码转换成十进制即可。

2. 大端存储和小端存储

  • 大端存储:把一个数据的低位字节的内容存放在高地址处高位字节的内容存放在低地址处
  • 小端存储:把一个数据的低位字节的内容存放在低地址处高位字节的内容存放在高地址处

了解了大端小端的概念之后,让我们设计一个小程序来判断当前机器的字节序吧!

#include 
int check_sys()
{
	int i = 1;
	return (*(char *)&i);
}
int main()
{
	int ret = check_sys();
	if(ret == 1)
	{
		printf("小端\n");
	}
	else
	{
		printf("大端\n");
	}
	return 0;
}

二、浮点型在内存中的存储

根据国际标准IEEE 754,任意一个二进制浮点数V可以表示成下面的形式:

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

举例来说:

  1. 十进制的5.0,写成二进制是 101.0 ,相当于 1.01×2^2 。那么,按照上面V的格式,可以得出S=0M=1.01E=2
  2. 十进制的-5.0,写成二进制是 -101.0 ,相当于 -1.01×2^2 。那么,按照上面V的格式,可以得出S=1M=1.01E=2

IEEE 754规定:

  1. 对于32位的浮点数,最高的1位是符号位S,接着的8位是指数E,剩下的23位为有效数字M【C语言】整型和浮点型在内存中如何存储_第5张图片

  2. 对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。 【C语言】整型和浮点型在内存中如何存储_第6张图片

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

  1. 1≤M<2 ,即M可以写成 1.xxxxxx 的形式,其中xxxxxx表示小数部分
    • 在计算机内部保存M时,默认第一位为1,因此可以被舍去,只保存后面的xxxxxx部分
      • 比如保存1.01的时候,只保存01,等到读取的时候,再把第一位的1加上去
    • 这样做的目的,是节省1位有效数字
  2. E是一个无符号整数,但是我们知道,科学计数法中是可以出现负数的,所以IEEE 754规定,内存中E的真实值必须要再加上一个中间数
    • 对于8位的E,这个中间数是127
    • 对于11位的E,这个中间数是1023
      • 比如E=10,保存成32位浮点数时,必须保存成10+127=137,即10001001

你可能感兴趣的:(C语言重点突破,c语言,开发语言)