【C语言】知识点一:数据在内存中的存储

一、数据类型介绍

在这里插入图片描述

二、整型在内存中的存储:原码、反码、补码

1、二进制、八进制、十进制、十六进制

名称介绍举例
二 进 制(Binary_system)逢2进1,由0和1两个数字组成。01000001
八 进 制(Octal_number)逢8进1,由0-7数字组成,为了区分与其它进制的数字区别,开头都是以0(零)开始。0101
十 进 制 (Decimalism)逢10进1,由0-9数字组成。65
十六进制(Hexadecimal)逢16进1,由0-9和A-F组成,为了区分于其它数字的区别,开头都是以0x(零)开始。0x41

2、进制间整数的相互转换

	2.1十进制VS二进制:
		2.1.1十进制转二进制:
			原理:除以2,直到商为0,最后反向取余数。
			举例:9(D)->1001(B)

在这里插入图片描述

		2.1.2二进制转十进制:
			原理:2为底数,权重为指数,乘以二进制位的累加。
			举例:1001(B)->9(D)

在这里插入图片描述

	2.2十进制VS八进制:
		2.2.1十进制转八进制:
			原理:除以8,直到商为0,最后反向取余数。
			举例:99(D)->0143(o)

在这里插入图片描述

		2.2.2八进制转十进制:
			原理:8为底数,权重为指数,乘以八进制位的累加。
			举例:0143(O)->99(D)

在这里插入图片描述

	2.3十进制VS十六进制:
		2.3.1十进制转十六进制:
			原理:除以16,直到商为0,最后反向取余数。
			举例:266(D)->0x10A(H)

在这里插入图片描述

		2.3.2十六进制转十进制:
			原理:16为底数,权重为指数,乘以十六进制位的累加。
			举例:0x10A(H)-> 266(D)

在这里插入图片描述

	2.4二进制VS八进制:
		2.4.1二进制转八进制:
			方法一:取三合一法
				原理:三位二进制位合为一位八进制位,权重只有0、1、2。
				举例:1001100(B)-> 114(O)
			方法二:十进制转换
				原理:二进制二进制先转换成十进制,再转化成八进制,方法同前。

在这里插入图片描述

		2.4.2八进制转二进制:
			方法一:取一解三法
				原理:一位八进制位分解为三位二进制位(可以口算)。
				举例:114(O) -> 1001100(B)
			方法二:十进制转换
				原理:八进制先转换成十进制,再转化成二进制,方法同前。

在这里插入图片描述

	2.5二进制VS十六进制:
		2.5.1二进制转十六进制:
			方法一:取四合一法
				原理:四位二进制位合为一位十六进制位,权重只有0、1、2、3。
				举例:1001100(B)-> 4C(Ox)
			方法二:十进制转换
				原理:二进制先转换成十进制,再转化成十六进制,方法同前。

在这里插入图片描述

		2.5.2十六进制转二进制:
			方法一:取一解四法
				原理:一位十六进制位分解为四位二进制位(一般可以口算)
			方法二:十进制转换
				原理:十六进制先转换成十进制,再转化成二进制,方法同前。
	2.6八进制VS十六进制:
		2.6.1八进制转十六进制:
			方法:十进制转换
				原理:八进制先转换成十进制,再转化成十六进制,方法同前。
		2.6.2十六进制转八进制:
			方法:十进制转换
				原理:十六进制先转换成十进制,再转化成八进制,方法同前。		

3、原码、反码、补码

计算机中的整数有三种二进制表示方式,即原码、反码和补码,三种表示方式均有符号位和数值位,符号位在最高位,用0表示正数,用1表示负数。

3.1正数的原码、反码、补码

介绍:正数的原码、反码、补码相同
举例:245(D)->0000 0000 0000 0000 0000 0000 1111 0101(B)(4个字节)
原码:0000 0000 0000 0000 0000 0000 1111 0101
反码:0000 0000 0000 0000 0000 0000 1111 0101
补码:0000 0000 0000 0000 0000 0000 1111 0101

3.2负数的原码、反码、补码

介绍:负数的原码、反码、补码各不相同
原码:直接按照规则转换成二进制即可;
反码:原码符号位不变,其余位按位取反;
补码:反码加1得到补码。
举例:-8(D)-> 1000 0000 0000 0000 0000 0000 0000 1000 (B)
原码:1000 0000 0000 0000 0000 0000 0000 1000
反码:1111 1111 1111 1111 1111 1111 1111 0111
补码:1111 1111 1111 1111 1111 1111 1111 1000

3.3原码、补码的相互转换

方法一
在这里插入图片描述
方法二
在这里插入图片描述

4、整型在内存中的存储

数据在内存中存放的是补码(打印是打印数据的原码),原因在于使用补码可以将符号位和数值域统一处理,同时加法和减法也可以统一处理(CPU只有加法器),此外,补码与原码的相互转换,其运算过程是相同的,不需要额外的硬件电路。
用VS观察负数在内存中的存储
举例:-8(D)-> 1000 0000 0000 0000 0000 0000 0000 1000 (B)
原码:1000 0000 0000 0000 0000 0000 0000 1000
反码:1111 1111 1111 1111 1111 1111 1111 0111
补码:FFFFFFF8
截图:所以验证了数据在内存中存放的是补码。
在这里插入图片描述

三、大小端字节序介绍及判断

1、为何有大端和小端

拿int数据类型举例,一个int数据占4个字节,分别将4个字节放入内存的方法各不相同,按照前后顺序一次存入符合逻辑,现在看来顺序放置是具备协调美的(嘿嘿),由于数据有正反顺序,所以导致数据在内存中的存放也分为两种模式,科学家给它们命名为“大端存储模式”和“小端存储模式”。

2、什么是大端和小端

大端模式:数据的低位保存在内存的高地址中,数据的高位保存在内存的高地址中。
如图所示
在这里插入图片描述
小端模式:数据的低位保存在内存的低地址中,数据的高位保存在内存的低地址中。
如图所示
在这里插入图片描述

3、怎么判断大端小端

解释:利用强制类型转换,将占4个字节的整型变量a=1存入内存,1在最低位,强制用char*类型的指针强制往后访问一个字节,如果解引用强制访问的这个字节等于1,说明是低位数据往低地址存放,为小端存储,如果不等于1,说明低位数据存放在高地址去了,为大端存储。
代码

#include <stdio.h>
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;
}

四、有关数据打印的例子

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;
}

过程解析
在这里插入图片描述

2、代码例子二

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

过程解析
在这里插入图片描述

3、代码例子三

//输出什么?
#include <stdio.h>
int main()
{
    char a = 128;
    printf("%u\n",a);
    return 0;
}

过程解析
在这里插入图片描述

4、代码例子四

#include <stdio.h>
int main()
{
int i= -20;
unsigned  int  j = 10;
printf("%d\n", i+j); 
return 0
}
//按照补码的形式进行运算,最后格式化成为有符号整数

过程解析
在这里插入图片描述

5、代码例子五

//输出什么?
#include <stdio.h>
int main()
{
unsigned int i;
for(i = 9; i >= 0; i--)
{
    printf("%u\n",i);
}
return 0;
}

过程解析
在这里插入图片描述

signed int的范围为
正数:00000000 00000000 00000000 00000000->01111111 11111111 11111111 11111111负数:11111111 11111111 11111111 11111111->10000000 00000000 00000000 00000000
正数: 0->7F FF FF FF
负数:-7F FF FF FF->0
图示如下
在这里插入图片描述
unsigned int的范围为:00 00 00 00->FF FF FF FF->00 00 00 00

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

1、浮点数二进制转换规则

整数部分:整数部分除以2取余101。
小数部分:小数部分乘以2取整.1。
如图
在这里插入图片描述

2、浮点数存储规则

在这里插入图片描述

举例
在这里插入图片描述

3、IEEE 754规定

对于32位的浮点数,最高的1位是符号位S,接着的8位是指数E,剩下的23位为有效数字M。
如图
在这里插入图片描述
对于64位的浮点数,最高的1位是符号位s,接着的11位是指数E,剩下的52位为有效数字M。
如图
在这里插入图片描述

4、指数E的规则

存入内存:E+127/1023后转为二进制
取出内存
1、E不全为0或不全为1:即指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第一位的1。
2、E全为0:浮点数的指数E等于1-127=-126(或者1-1023=-1022)即为真实值,有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数。
3、E全为1:如果有效数字M全为0,表示±无穷大(正负取决于符号位s)。

5、举例介绍

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;
}

过程解析
在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一直学不会编程的小徐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值