说到数据在内存中的布局问题就不得不提到另一个概念:大端和小端。
存储地址内的排列则有两个通用规则。一个多位的整数将按照其存储地址的最低或最高字节排列。如果最低有效字节在最高有效字节的前面,则称小端序;反之则称大端序。
先来看个实际例子。
1 | int i = 1 << 15; |
如果是大端机器,i的布局是0x00 0x00 0x80 0x00,s所对应的就是0x00 0x00,即0。
如果是小端机器,i的布局是0x00 0x80 0x00 0x00,s所对应的就是0x00 0x80,即-32768。
再来看个例子加深下理解。
1 | float f = 7.0; |
7.0 = 1.75 * 2 ^ (129 - 127)
在大端机器中,对应的内存分布是一个0,接下来八位是10000001,接下来是两个1,后面都是0。s对应的是一个挺大的数字。在小端机器中,按照字节翻转,后面的0都跑前面来了,那么s就是0。
我们可以用一个简单的程序来检测到底是大端还是小端(当然,上面的两个例子也能检测)
1 | int i = 1; |
现在的机器几乎都是小端了,这是为什么呢?小端机器有什么好处呢?
StackOverflow和StackExchange上的答案类似:
使用同样的地址,可以使用不同的长度去读取一个变量。比如32bit的值,我们想读8bit或者16bit,直接读就好了,结果就是我们想要的,如果是大端,计算机还要计算偏移量再读取。
不过,在Quora上最高票答案是一个CPU Designer的回答,说是几乎没有什么区别。就和大端小端的来源一样,你会关心敲鸡蛋先敲开哪一端吗?
对于大多数程序员而言,现成的工具/库都考虑了这个问题,不用自己操心。不过,还是知道这个知识点比较好,说不准那天程序没有跑对就是因为这个呢?是吧。还有一点,万一面试的时候用呢。