2024-07-15记 - 1
作者(Author):仟濹 (网名)
今天看比特的网课
第一次接触大小端的知识,在这记录一下,为了总结,也为了后期复盘。
这也是我第一次写博客,写的不咋地哈哈
如何理解数据的“高字节”和“低字节”?
举例:-10
整型用4个字节存储,4byte = 4 * 8 bit
源码
二进制: 10000000 00000000 00000000 00001010 -> 可以用8位2进制数 表示 1个字节
十六进制: 0x80 0x00 0x00 0x0a -> 可以用2位16进制数 表示 1个字节
0x80就是高字节
0x0a就是低字节
如何理解内存的“低地址”和“高地址”?
低地址:内存中数据的起始位置,存储数据的开始部分。
高地址:内存中数据的结束位置,存储数据的末尾部分。
低地址 | 高地址 |
内存中的字节存储顺序一般只有两种,“大端序”和“小端序”
- 大端字节序就是将 最高有效字节 存储在 最低的内存地址 上。
- 小端字节序就是将 最高有效字节 存储在 最高的内存地址 上。
如何更好的理解呢?下面作图理解。
比如随便写一个用16进制表示的数据:
11 22 33 44
11 为高字节,44为低字节
-
大端 字节序存储
将“高字节” 放在 “低地址” ,将 “低字节” 放在 “高地址”。
更好的理解是大端就是正着存的。
把一个数据的
高位字节
存放在低地址处
,把低位字节存
放在高地址处
,就是大端字节序存储。
11(高字节) | 22 | 33 | 44(低字节) |
低地址 | 高地址 |
-
小端 字节序存储 VS 在X68中就是使用的低端字节序存储的
将“低字节” 放在 “高地址” ,将 “高字节” 放在 “低地址”。
更好的理解是小端就是反着存的。
把一个数据的
高位字节
存放在高地址处
,把低位字节序存
放在低地址处
,就是小端字节序存储。
44(低字节) | 33 | 22 | 11(高字节) |
低地址 | 高地址 |
注:对于char这种只有一个字节的数据来说,存储数据的时候没有大小端之说,可以理解为, 如何分辨大小端是看的字节的顺序。
如何写一个程序,来判断是用的什么字节序呢??
思路如下:
先定义一个变量,初始化为1,如 int num = 1;
00000000 00000000 00000000 00000001 == 0X01 00 00 00
让数据 1 以整型的形式存到内存当中,会有2种方式存储,即大端和小端。
0X01 - 高位的字节 0X00 - 低位的字节
通过判断低地址处存储的是高位字节还是低位字节就可判断出来是大端还是小端了。
如果存的是高位字节,就是大端
如果存的是低位字节,就是小端
关键代码:(char*)&a --> int*
(char*)&a --> int*
1. &a就是先求出a地址,然后将int类型的地址强制转换成char类型的地址
2. *(char*)&a 就只访问一个字节的内容了
然后让01[其实应该是00001]以 10 进制的形式打印
要么打印出来为 1 ,要么打印出来为 2
char* 和 int* 什么意思???
char* 就表示 char 类型的地址
int* 就表示 int 类型的地址
下面再解释一遍
加深我自己的理解
如果是大端,存储的就是
01 | 00 | 00 | 00 |
---|---|---|---|
低地址 | 高地址 |
如果是小端,存储的就是
00 | 00 | 00 | 01 |
---|---|---|---|
低地址 | 高地址 |
因为char
没有高端字节序和低端字节序之说(只有一个字节),所以利用强制转换的特性,可以将int
强制转换成char
。
这样就将原来的在内存中存储的 4 个字节变成了 1 个字节
那么保留的是哪个字节呢???
保留的是低地址的字节
所以利用强制转换后保留低地址的字节的特性,就可以知道低地址存储的是【高位】字节序,还是【低位】字节序了
-
如果是【高位】字节,就证明是按照【大端】字节序存储的
-
如果是【低位】字节,就证明是按照【小端】字节序存储的
如何判断大小端呢??
//判断是大端字节序存储还是低端字节序存储
//作者(Author):仟濹
//创作时间: 2024-07-15
//完成时间: 2024-07-15
#include <stdio.h>
int check_sys1();
int check_sys2();
int check_sys3();
int main()
{
int check;
//如果是0001就证明是【小端】字节序存储,如果是0000就证明是【大端】字节序存储
//一定要是1这种数字,方便判断低地址(开头的内存地址)存放的是0000还是0001,
//大端返回0,小端返回1
if(check_sys1())
printf("小端字节序存储\n");
else
printf("大端字节序存储\n");
if(check_sys2())
printf("小端字节序存储\n");
else
printf("大端字节序存储\n");
if(check_sys3())
printf("小端字节序存储\n");
else
printf("大端字节序存储\n");
}
int check_sys1()//同一种思路第一种写法
{
//如果是0001就证明是【小端】字节序存储,如果是0000就证明是【大端】字节序存储
int num = 1;//一定要是1这种数字,方便判断低地址(开头的内存地址)存放的是0000还是0001,
return *(char*)#
}
int check_sys2()//同一种思路第2种写法
{
//如果是0001就证明是【小端】字节序存储,如果是0000就证明是【大端】字节序存储
int num = 1;//一定要是1这种数字,方便判断低地址(开头的内存地址)存放的是0000还是0001,
int p = *(char*)#
return p;
}
int check_sys3()//同一种思路第3种写法
{
//如果是0001就证明是【小端】字节序存储,如果是0000就证明是【大端】字节序存储
int num = 1;//一定要是1这种数字,方便判断低地址(开头的内存地址)存放的是0000还是0001,
char *p = (char*)#
return *p;
}
目前学习的关于大端字节序和小端字节序的知识差不多就这些了,后续可能会对其进行改正和补充。