数据的存储,如何理解内存中的“0”和“1”

目录:

  1. 数据类型介绍
  2. 整形在内存中的存储:原码、反码、补码
  3. 大小端字节序介绍及判断
  4. 浮点型在内存中的存储解析

1.数据类型介绍
char //字符数据类型
short //短整型
int //整形
long //长整型
long long //更长的整形
float //单精度浮点数
double //双精度浮点数

1.1基本类型归类
1整形

char
unsigned char
signed char
short
unsigned short[int]
signed short[int]
int
unsigned int
signed int
long
unsigned long[int]
signed long[int]

2浮点数家族

float
double

3构造类型

数组类型
结构体类型 struct
枚举类型 enum
联合类型 union

4指针类型

int pi;
char pc;
float pf;
void pv;

5空类型

void 表示空类型(无类型)
通常应用于函数的返回类型、函数的参数、指针类型

2.1整形在内存中的存储:原码、反码、补码
1对于负数而言:

原码:直接将二进制按照正负数的形式翻译成二进制就可以。
反码:将原码的符号位不变,其他位依次按位取反就可以得到了。
补码:反码 + 1就得到补码。
2对于正数
正数的原、反、补码都相同。

对于整形来说:数据存放内存中其实存放的是补码。————重点
内存中存储的都是补码 且顺序是相反的

#include<stdio.h>
int main()
{
 int a = 0x12345678;
 return 0;
}
例:
a在内存中的存储为 78 56 34 12

3. 大小端字节序介绍及判断
大端(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;
小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位, ,保存在内存的高地址中。

判断其在内存中存在为大小端? 小端

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

相关练习题

#include <stdio.h>
int main()
{
 char a = -1; 正常模式下的char
 signed char b = -1; 整形模式下的char
 unsigned char c = -1; 正形模式下的char unsigned表示这个定义下的数字全部为正数
 printf(“a=%d,b=%d,c=%d”, a, b, c);
 return 0;
}
a = -1; b = -1; c = 255;
#include <stdio.h>
int main()
{
 char a = -128;
 printf(%u\n”, a);
 return 0;
}
10000000 00000000 00000000 10000000 原码
11111111 11111111 11111111 01111111 反码
11111111 11111111 11111111 10000000 补码
因为 %U 是打印无符号数 所以打印
01111111 11111111 11111111 10000000
即为 429 496 7168
#include <stdio.h>
int main()
{
 char a = 128;
 printf(%u\n”, a);
 return 0;
}

char类型在内存中的大小存贮为
0 1 2 3 4 5 6 7 ,,,,125 126 127 -128 -127 -126 ,,,,,,-3 -2 -1 然后继续0 2 3 4 周而复始
所以128 = -128
#include <stdio.h>
int main()
{
 int i = -20;
 unsigned int j = 10;
 printf("%d ", i + j);
 return 0;
}

-20 1,00010100 原码
 1,11101011 反码
 1,11101100 补码
10 0,00001010 原码=反码= 补码
 1,11110110 结果 补码
 1,11110101 反码
1,00001010 原码 即为-10
结果为10
#include<stdio.h>
int main()
{
 unsigned i;
 for (i = 9; i >= 0; i++)
 printf(%u\n”, i);
 return 0;
}
当i从90时,正常, 当i=0时,i-1=-1) 因为是unsigned 所以i-1 = 1 然后就死循环
#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;
}
结过为 255
char 的大小为 012345 127 -128 -127 -126 -3-2-1 012345
#include <stdio.h>
unsigned char i = 0;
int main()
{
 for (i = 0; i <= 255; i++)
 {
 printf(“hello world\n”);
 }
 return 0;
}
255+1=0;所以死循环打印 hello wolrd

类比一下 其余类型也一样都有最大值与最小值,周而复始的运行 从0 到最大然后到最小

3.1浮点型在内存中的存储

常见的浮点数:3.14159 1E10
浮点数家族包括: float、double、long double 类型。
浮点数表示的范围:float.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.n在内存中存储为:0000 0000 0000 0000 0000 0000 0000 1001
第一个数据正常读取
2.float pFloat = (float )&n;
这句代码含义是: 将数据类型为int
的n的地址转换称为float
类型,放在pFloat
我们知道 数据在内存中存储是固定的格式的,数据类型取决于如何把数据拿出来
也就是说上面代码中第二个让我们把0000 0000 0000 0000 0000 0000 0000 1001按照float
类型输出:
0 01111110 00000000000000000001001
按照float*类型格式上述二进制可以写为:
(-1)^S * M * 2^E = (-1)0*0.00000000000000000001001*2(-126)
也即是一个非常接近零的数字
3.*pFloat = 9.0;的含义:将9.0这个浮点数存储在二进制中,即:
0 00001001 0000000000000000000000
第三个输出即将上述二进制数字用 整形的形式表达出来
4.第四个输出即为:将3中的二进制用float类型表达出来

num 和 *pFloat 在内存中明明是同一个数,为什么浮点数和整数的解读结果会差别这么大? 要理解这个结果,一定要搞懂浮点数在计算机内部的表示方法。
详细解读:
根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式:
(-1) ^ S * M * 2 ^ E
(-1) ^ s表示符号位,当s = 0,V为正数;当s = 1,V为负数。
M表示有效数字,大于等于1,小于2。
2 ^ E表示指数位。
举例来说: 十进制的5.0,写成二进制是 101.0 ,相当于 1.01×2 ^ 2 。 那么,按照上面V的格式,可以得出s = 0,M = 1.01,E = 2。
十进制的 - 5.0,写成二进制是 - 101.0 ,相当于 - 1.01×2 ^ 2 。那么,s = 1,M = 1.01,E = 2。
IEEE 754规定: 对于32位的浮点数,最高的1位是符号位s,接着的8位是指数E,剩下的23位为有效数字M。
在这里插入图片描述
对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。
在这里插入图片描述
特别提醒:M是一个1<M<2的数字,它的第一位绝对是一,所以我们可以省略这个一,以能够表示更准确的数字
E这个数字在8位和11位时,会出现负数,那么我们就需要给其加上一个127或者1023,使其变成一个整数
E不全为0或不全为1
这时,浮点数就采用下面的规则表示,即指数E的计算值减去127(或1023),得到真实值,再将有效数字M前
加上第一位的1。 比如: 0.5(1 / 2)的二进制形式为0.1,由于规定正数部分必须为1,即将小数点右移1位,
则为1.0 * 2 ^ (-1),其阶码为 - 1 + 127 = 126,表示为01111110,而尾数1.0去掉整数部分为0,补齐0到23位
00000000000000000000000,则其二进制表示形式为:
0 01111110 00000000000000000000000
E全为0
这时,浮点数的指数E等于1 - 127(或者1 - 1023)即为真实值, 有效数字M不再加上第一位的1,而是还原为
0.xxxxxx的小数。这样做是为了表示±0,以及接近于0的很小的数字。
E全为1
这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位s);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值