union是共享存储单元的数据结构,它所占用的内存长度等于最长的成员的内存长度。
struct的大小取决于它所有的成员的内存长度之和(理论上是这样的,实际上还得考虑它的存储方式是否边界对齐)。
以一个例子来说明边界对齐,大端和小端方式
现有一个int变量x为 0x12345678,假设主存地址为32位(以字节编址,也就是主存的大小位2的32次方4GB)
存储方式为以边界对齐
假设系统为x分配的地址为0x80100000(以边界对齐存储int4B大小,按字节编址,所以地址一定要是4的整数倍,地址的最低两位二进制位一定要是00,而不可能是01,10,11这三种情况)
以边界对齐的存储方式可以减少访存的次数,是一种以空间换时间的思想。例如数据线32位,要访问一个32位的字的指令,以边界对齐方式只需要访存一次,而不以边界对齐可能要访问两次,从而影响了指令的执行效率。
大端方式:
地址
0x80100000 12H
0x80100001 34H
0x80100002 56H
0x80100003 78H
小端方式:
地址
0x80100000 78H
0x80100001 56H
0x80100002 34H
0x80100003 12H
下面来看一段代码:
就是把各类型的字节数输出,以及对union的操作检测是大端还是小端的方式
#include <iostream>
#include<stdio.h>
using namespace std;
typedef struct Node{
char a;
long b;
float c;
}a;
union T{
char a;
int b;
}t;
int main()
{
cout<<sizeof(char)<<endl;
cout<<sizeof(long)<<endl;
cout<<sizeof(float)<<endl;
cout<<sizeof(a)<<endl;
cout<<sizeof(t)<<endl;
t.b=0xffffff01;
printf("%d\n",t.b);
printf("%d\n",t.a);
return 0;
}
以及运行结果:
1代表的char的字节数,4代表的long的字节数,4代表的float的字节数。
结构体Node的一个变量a的字节数是12,union T的一个变量t的字节数为4。
将t.b以%d整数的形式将其输出为-255,t.a以%d整数的形式将其输出为1。
Node a的大小为12B而不是9B的原因是采用了边界对齐的方式,结构体的大小为其最宽基本类型的整数倍,4B的整数倍。
T t.a输出的是union的第一个字节单元的内容,为1说明是采用的小端的存储方式,如果是-1说明是大端的存储方式。