union和大端小端

大端: 低位的数据存放在高地址,高位的数据存放在低地址
小端: 低位的数据存放在低地址,高位的数据存放在高地址

现在的CPU一般都是小端. 网络编程中,TCP/IP统一采用大端方式传送数据,所以有时我们也会把大端方式称之为网络字节序

结合union理解这个概念比较容易,看下面程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
union my{
int a;
char bytes[4];
};

my un;
un.a = 135201034;
// a为4个字节, 二进制表示就是: 00001000 00001111 00000001 00001010
// 分别转化为十进制就是 8 15 1 10
int a0 = static_cast<int>(un.bytes[0]) ;
int a1 = static_cast<int>(un.bytes[1]) ;
int a2 = static_cast<int>(un.bytes[2]) ;
int a3 = static_cast<int>(un.bytes[3]) ;

cout<< "address a0: "<< &a0 <<" "<<a0 <<endl;
cout<< "address a1: "<< &a1 <<" "<<a1 <<endl;
cout<< "address a2: "<< &a2 <<" "<<a2 <<endl;
cout<< "address a3: "<< &a3 <<" "<<a3 <<endl;

联合体占了4个字节,对a赋值后,显然bytes数组要分担这4个字节的数据,这里为了表示清楚,把每个bytes又转为int(四个字节),我们知道数组的内存地址占用是连续的,而且第一个元素在低地址,依次为高地址。

运行结果:

1
2
3
4
address a0: 0x7fff768cc180  10
address a1: 0x7fff768cc184 1
address a2: 0x7fff768cc188 15
address a3: 0x7fff768cc18c 8

可以看出转换后,每个占了4字节,低地址的a0对应的是a的低8位,所以说这里是小端. 如果是大端, 地址和数据的对应关系就要倒过来.