在看C++的时候,看到了union(共用体),同时想起在面试的时候,也经常被问到计算机大小端的测试方法,由此便写下这篇博文。
计算机的大小端问题由来已久,具体的历史大家可以看看维基百科里边是怎么简述的,还是挺不错的哦!~~
这里讲讲计算机里的大小端模式:
端模式 | 首字节 | 中间字节 | 尾字节 |
大端 | 最高有效位 | … | 最低有效位 |
小端 | 最低有效位 | … | 最高有效位 |
如果将一个16位的整数0x1234存放到一个短整型变量(short)中。这个短整型变量在内存中的存储在大小端模式由下表所示。
地址偏移 | 大端模式 | 小端模式 |
0x00 | 12 | 34 |
0x01 | 34 | 12 |
而在C语言中union是一个很特别的结构,它是把几种不同类型的变量存放到同一段内存中。而对union型成员的存取都是相对于该联合体基地址的偏移量为0处开始,也就是联合体的访问不论对哪个变量的存取都是从union的首地址位置开始的。利用这个特性,我们可以判断当前系统是大端还是小端。
下表可以很清晰的看出union在不同端模式下的存储方式:
大端模式 |
| 小端模式 | |||
地址偏移量 | 类型 | 地址偏移量 | 类型 | ||
short | char | short | char | ||
0x000000 | 12 | 12 | 0x000000 | 34 | 34 |
0x000001 | 34 | 系统数据 | 0x000001 | 12 | 系统数据 |
若以上述16位的整数0x1234为例 |
下面就看看如何用C语言的union来检测行x86CPU的端模式:
/*
Test environment: Dev-C++ 5.1.0.0
Test result:
The compute is little-endian.
*/
#include <stdio.h>
#include <stdlib.h>
union data
{
short inter;
char ch;
};
int main(void)
{
union data c;
c.inter = 0x1122;
if(c.ch == 0x22)
printf("The compute is little-endian.\n");
else
printf("The compute is big-endian,\n");
getchar();
return 0;
}