在看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;
}