结构体struct union -大端小段

来源:互联网 发布:ubuntu输入法不见了 编辑:程序博客网 时间:2024/05/16 01:31

1:大端与小端?与寻常习惯的区别? 
大端:高地址存储低位字节。 
小端:低地址存储低位字节。 
如对于数据0x1234,其32位为0x00001234。 
对于大端来说:(地址由低到高存储)00 00 12 34 
对于小端来说:(地址由低到高存储)34 12 00 00 
由此可以得出结论:大端的存储方式与寻常习惯相一致,而小端的存储方式为按照字节倒排。


在一个64位的操作系统中定义如下结构体:
1
2
3
4
5
6
structst_task
{
    uint16_t id;
    uint32_t value;
    uint64_t timestamp;
};
同时定义fool函数如下:
1
2
3
4
5
6
7
voidfool()
{
    st_task task = {};
    uint64_t a = 0x00010001;
    memcpy(&task, &a, sizeof(uint64_t));
    printf("%11u,%11u,%11u", task.id, task.value, task.timestamp);
}
上述fool()程序的执行结果为()

正确答案: 
1,0,0


首先在内存中是小端存储方式存放字节。
uint16_t id;//两个字节,16位,占2个 字节
uint32_t value;//4个字节,32位,占4个字节
uint64_t timestamp;//8个字节,64位,占8个字节

0x00010001十六进制,共32位

id(16bits)+16bits+value(32bits)=64位,以8字节字节对齐需要
按照低位存储:
则id(16bits)+16bits会占据掉32bits的 0x00010001,id占据掉Ox0001,因此为1

 
id和value占第一行8字节,timestamp占第二行8个字节。 故 memcpy复制8个字节的数据后,timestamp是没有值的。 
uint64_t a = 0x00010001是8个字节,故在64位系统中是占了一行,只赋值给第一行数据。
按照小端存储原理,低字节存放在低地址:01 00 01 00 , 00 00 00 00;
所以id占用01 00; value 占用00 00 00 00;timestamp没有值 ;

对struct进行sizeof操作 
对于一个struct取sizeof,要考虑对界的问题。对界是取struct中最大的数据作为对界值。对于以下三个struct,有以下解答

struct s1{  char a;  double b;  int c;  char d; };//sizeof(struct s1)=1+7+8+4+1+3=24;对界值取8(7,3是为满足对界填充的空间)struct s2{  char a;  char b;  int c;  double d;  };//sizeof(struct s2)=1+1+2+4+8=16;对界值取8(2是为满足对界填充的空间)struct X {     short s;     int i;     char c;};//sizeof(struct X)=2+2+4+1+3=12;对界值取4(第二个2和3是为满足对界填充的空间)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

union数据类型占用的空间

union u //8对齐{    double a;    int b;};union u2 //4对齐{   char a[13];   int b;};union u3 //1对齐{   char a[13];   char b;};cout<<sizeof(u)<<endl;  // 8cout<<sizeof(u2)<<endl;  // 16cout<<sizeof(u3)<<endl;  // 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

都知道union的大小取决于它所有的成员中,占用空间最大的一个成员的大小。所以对于u来说,大小就是最大的double类型成员a了,所以sizeof(u)=sizeof(double)=8。但是对于u2和u3,最大的空间都是char[13]类型的数组,为什么u3的大小是13,而u2是16呢?关键在于u2中的成员int b。由于int类型成员的存在,使u2的对齐方式变成4(4字节对齐),也就是说,u2的大小必须在4的对界上,所以占用的空间变成了16(最接近13的对界)。