25.1.1 硬件架构问题(2)
3. 字节顺序
所有现代计算机都存储二进制表示的数字,但是同一个数在两个平台上的表示可能不同。这听起来很矛盾,但您会看到,有两种读数的方法使得两个数字都有意义。
计算机内存中的一个槽通常都是一个字节,因为大部分计算机都是按字节寻址的。C++(www.cppentry.com)中的数字类型通常都是多字节的。例如,short可能是2个字节。假设程序中有下面这一行:
- short myShort = 513;
在二进制中,数字513表示为0000 0010 0000 0001。这个数字包含16个0或1,即16位。因为一个字节有8位,计算机需要2个字节来存储这个数字。因为每个内存地址都包含1个字节,计算机需要将这个数字分成多个字节。假设short是2个字节,这个数字将平均分解为两个部分。这个数字的上部分放在高字节中,下半部分放在低字节中。这种情况下,高字节为0000 0010,低字节为0000 0001。
现在数字已经被分解为内存大小的部分了,唯一剩下的问题如何把它们保存在内存中。两个字节是必要的,但字节的顺序是不清楚,事实上顺序取决于当前采用的系统硬件架构。
表示数字的一种方法是首先将高字节放在内存中,然后将低字节放在内存中。这种策略称为big-endian(大尾)顺序,因为数字中更大的一部分放在前面。PowerPC和Sparc处理器使用大尾顺序。其他一些处理器,如x86,将字节以相反的顺序保存,先把低字节放在内存中。这种方法称为little-endian(小尾)顺序,数字中更小的一部分放在前面。一个架构可以选择一种方法或另一种方法,通常是根据向后兼容性选择。"大尾"和"小尾"这两个术语早于现代计算机数百年就出现了。Joathan Swift在他18世纪的小说《格列夫游记》用这两个词描述了两个阵营对于用哪一头敲鸡蛋的争论。
不论某个架构使用的是什么顺序,您的程序使用数值的时候都不必关心底层机器使用的是大尾顺序还是小尾顺序。这个顺序只有在不同架构之间转移数据的时候才需要考虑。例如,如果通过网络发送二进制数据,则可能需要考虑其他系统使用的顺序。一个解决办法是使用标准的网络字节顺序(Network Byte Ordering),这个顺序始终是大尾顺序。因此,通过网络发送数据之前,将数据转换为大尾顺序,从网络接收的数据的时候,将数据从大尾顺序转换为底层系统使用的顺序。
同样,如果将二进制数据写入文件,您可能要考虑打开文件的系统使用不同字节顺序的情况。