2024 - 09 - 23 - 笔记 - 17
作者( Author ):郑龙浩 / 仟墨(网名)
二次梳理、复习大小端知识。
大小端介绍(重要)
1. 我上一次写的关于大小端的博客。
2. 如何理解数据的“高字节”和“低字节”?
举例:-10
整型用4个字节存储,4byte = 4 * 8 bit
源码
二进制: 10000000 00000000 00000000 00001010 -> 可以用8位2进制数 表示 1个字节
十六进制: 0x80 0x00 0x00 0x0a -> 可以用2位16进制数 表示 1个字节0x80就是高字节
0x0a就是低字节
以下使用16进制描述的,其实存储的时候是按照2进制来的。
例如:一个16bit的short型x,在内存中的地址为0x0010, x的值为0x1122 ,那么0x11为高字节,0x22 为低字节。
对于大端模式,就将 0x11 放在低地址中,即 0x0010 中,0×22 放在高地址中,即 0x0011 中。
小端模式,刚好相反。
我们常用的 ×86 结构是小端模式,而 KEILC51 则为大端模式。
很多的ARM,DSP都为小端模式。
有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。
3. 如何理解内存的“低地址”和“高地址”?
低地址:内存中数据的起始位置,存储数据的开始部分。
高地址:内存中数据的结束位置,存储数据的末尾部分。
低地址 高地址
4. 内存中的字节存储顺序一般只有两种,“大端序”和“小端序”
- 大端字节序就是将 最高有效字节 存储在 最低的内存地址 上。
- 小端字节序就是将 最高有效字节 存储在 最高的内存地址 上。
5. 如何更好的理解【大端】字节序 和 【低端】字节序呢???下面作图理解😄
图片是截屏,来源于看的一个网课
比如随便写一个数据: 11 22 33 44
11 22 33 44
即0x11 0x22 0x33 0x44
, 11一个字节,22一个字节,总共四个字节11就是【高位字节】,44就是【低位字节】,
数据中,左侧是高位,右侧是低位。
① 大端【字节序】存储 低地址 11 22 33 44 高地址 低地址(存储高字节) --> 高地址(存储低字节)存储
大端就是把高位字节序放到了前面。
更好的理解是大端就是正着存的。
把一个数据的
高位字节
的内容存放在低地址处
,把低位字节
的内容放在高地址处
,就是大端字节序存储。
11(高字节) 22 33 44(低字节) 低地址 高地址
② 小端【字节序】存储低地址 44 33 22 11 高地址 低地址(存储低字节) --> 高地址(存储高字节)存储
(VSX86使用)
小端就是把低位字节序放到了前面。
更好的理解是小端就是反着存的。
把一个数据的
高位字节
的内容存放在高地址处
,把低位字节
的内容放在低地址处
,就是小端字节序存储。
44(低字节) 33 22 11(高字节) 低地址 高地址
注:对于char这种只有一个字节的数据来说,存储数据的时候没有大小端之说,可以理解为, 如何分辨大小端是看的字节的顺序。
③ 乱序存储 - 名字我乱取的,我也不知道这种叫什么
其实还有一种是以乱着的顺序存储的,没有实际的顺序,不过好像没有按照这种方式去存的编译器哈哈哈哈哈
6. 为什么会有大小端呢???
一个字节没有,但是数据如果是多个字节,就要有存放顺序了,那么这个顺序如何规定呢,就有了大小端。
注: 什么顺序存进去的,就要按照什么顺序出来。
7. 【百度2015年系统工程师笔试题】判断机器是用的什么字节序?(判断机器用的大小端?)
在此之前要明白一点,当整型强制转换成字符型的时候,只保留最低地址的一个字节,利用这个特性,就可以判断出来该机器是用的什么字节序了。
97. 【C语言进阶】数据存储_数据类型:整型存储和大小端_哔哩哔哩_bilibili
请简述大端字节序和小端字节序的概念,设计一个小程序来判断当前机器的字节序。
① 思路:
(char)&a --> int
先&a就是求出a地址,然后将【int类型的地址】强制转换成【char类型的地址】
然后 *(char*)&a 就只访问一个字节的内容了
然后让01[其实应该是00001]以 10 进制的形式打印
要么打印出来为 1 ,要么打印出来为 2
② char* 和 int* 什么意思???
char* 就表示 char 类型的地址
int* 就表示 int 类型的地址
③ 下面再解释一遍
为了加深自己的理解,再梳理一遍思路
我的理解:
下面的数字是 十进制 1 的二进制形式
00000000 00000000 00000000 00000001 == 0x00 0x00 0x00 0x01
让数据 1 以整型的形式存到内存当中,会有2种方式存储,即大端和小端。
如果是【大端】,存储的就是
00 00 00 01 低地址 高地址 如果是【小端】,存储的就是
01 00 00 00 低地址 高地址 因为
char
没有高端字节序和低端字节序之说(只有一个字节),所以利用强制转换的特性,可以将int
强制转换成char
。(原本的n个字节强制变成只有1个字节)样就将原来的在内存中存储的 4 个字节变成了 1 个字节
所以利用强制转换后保留低地址的字节的特性,就可以知道低地址存储的是**【高位】字节序,还是【低位】**字节序了
- 如果是**【高位】字节序,就证明是按照【大端】**字节序存储的
- 如果是**【低位】字节序,就证明是按照【小端】**字节序存储的
那么保留的是哪个字节呢??? 保留的是低地址的字节
下面是网课中截的屏。
(三种写法)思路大差不差
//判断是大端字节序存储还是低端字节序存储
//作者(Author):郑龙浩(Zheng Longhao)
//创作时间: 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(二进制为:00000000 00000000 00000000 00000001)这种数字,方便判断低地址(开头的内存位置,即低地址位置)存放的是0000还是0001,
char *p = (char*)#
return *p;
}