漫长学期的预告

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

基本概念

大端小端表示,一个数字在内存中或硬盘上记录时,是高位在前或在后,高位在前就是大端(BigEden),在后就是小端(samllEden)。

我们日常记录和代码里定义一千二百三四如:

int a = 1234;

就是大端记录。

如果是小端的一千二百三十四:就是"4321"了。

 

通常应用

一般而言,平台使用的大小端类型分别是:

小端:x86、ARM、win

大端:PowerPC

在操作系统上小端应用得更广泛些,但网络传输中(网络序)采用的是大端,一般系统上自带转换函数。

 

判断本机是大端还是小端

以C++ 为例

1     bool IsSmallEden (){
2         int i = 1;
3         char* p = (char*)&i;
4         bool b = (*p == 1); // == 1 说明小头
5         return b;
6     }

原理:定义一个数i=1,其占字节数为4,判断其最低位的位置是否为1,即可。为1说明低位编码放在前面了,说明是小端,否则就是大端。

Java同样,可以取int的高低位byte进行为1验证。

 

思考例题

下面打印的结果是多少呢?

1 char a[5] = "1234";
2 
3 int *ptr = (int*)a;
4 
5 printf("%x\r\n", *ptr);

 

答案解析

根据机器samllEden / bigEden类型不同打印结果不同。

行3: 将a[] 转换为了 int*,也就是说用"1234"来表示了一个本机整数编码。注意此值的实际整数值可能与我们预期较远为:

52 * (256*256*256) + 51 * (256*256) + 50 * 256 + 49 = 875770417。

其含义为 52, 51, 50, 49 分别为4, 3, 2, 1的ASCII编码,几个256相乘分别代表其在int 的4个字节中所占的编码位置,52, 51, 50, 49按顺序分别对应从高到低的4位。

PS:开始本帅也以为,1234转int后在4个字节上的编码值分别应该是1234,无非就是个高低位的区别,可实际是每个位置上是这些值的ASCII编码。

所以第五5行打印结果就是(环境win10):

34333231

34, 33, 32, 31分别为 4 3 2 1 ASCII编码的十六进制表示。

也就是说

int的实际值(就是打印值)是'4' * (256*256*256) + '3' * (256*256) + '2' * 256 + '1' "4321" ,高位是4,而实际显示字符串显示是第一行  char a[5] = "1234"; 的定义高位是1。就是我们看到的1234在内存是4321的方向,字符串定义理解为我们看到的方向,打印结果理解为实际值的方向。

另外:如果我们正常定义

int a = 1234;

print(a);

这样打印结果是正常的 1234,因为在定义和查看,我们日常默认的都是大端,在输入输出时程序里自动进行的大小端,就无需担心了。

 

posted on 2023-08-06 09:33  漫长学期的预告  阅读(19)  评论(0编辑  收藏  举报