结构体struct union -大端小段

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


在一个64位的操作系统中定义如下结构体:
1
2
3
4
5
6
struct st_task
{
     uint16_t id;
     uint32_t value;
     uint64_t timestamp;
};
同时定义fool函数如下:
1
2
3
4
5
6
7
void fool()
{
     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;  // 8
cout<<sizeof(u2)<<endl;  // 16
cout<<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的对界)。 




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 结构体struct)和联合体(union)都是C语言中用于定义自定义数据类型的方式,它们的区别在于: 1. 结构体中的各个成员在内存中是分开存储的,而联合体中的各个成员在内存中是共用同一块空间的。 2. 结构体的大小至少是其各个成员大小之和,因为每个成员都需要占用一定的内存空间,而联合体的大小则是其最大成员的大小,因为联合体中只有一个成员会被使用,其它成员则会被浪费。 3. 结构体中的各个成员可以同时被访问和修改,而联合体中只有一个成员可以被访问和修改。 4. 结构体可以存储不同类型的成员,而联合体只能存储同一类型的成员。 总之,结构体适合用于存储多个不同类型的数据,而联合体适合用于存储多个相同类型的数据,且只有一个数据会被使用的情况。 ### 回答2: 结构体struct和联合体union都是在C语言中用来组织多个不同类型的变量的一种方式。它们的区别在于变量的存储方式和内存占用。 结构体struct是一种可以存储不同类型的变量的自定义数据类型。它通过定义多个不同类型的变量,并将它们组合在一起,形成一个新的类型。结构体中的每个成员变量都使用独立的内存空间,大小根据成员变量的类型而定。结构体的成员可以同时存在于内存中,因此结构体可以存储和处理多个不同类型的数据。 联合体union也是一种可以存储不同类型的变量的自定义数据类型。它与结构体不同的是,联合体的成员变量共享同一块内存空间,也就是说,联合体的各个成员变量会在同一时间占用该内存空间。联合体的内存空间大小会根据最大的成员变量类型来决定。而为了节约内存空间,联合体只能同时存储和处理一个成员的数据。 结构体和联合体的使用方式也不同。结构体通常用于组织多个相关的变量,可以同时访问和修改结构体的各个成员变量。而联合体通常用于存储不同类型的变量,根据不同的需求来访问和修改特定的成员变量。 综上所述,结构体和联合体在存储方式、内存占用和使用方式上都有所不同,开发者要根据实际需求选择合适的数据类型。 ### 回答3: 结构体struct和联合体union是C语言中的两种复合数据类型。 结构体struct允许将不同类型的变量(如整型、字符型、浮点型等)组合在一起,形成一个逻辑上的整体。它可以定义多个成员变量,每个成员变量可以有不同的数据类型和名称。通过使用结构体,可以更方便地管理和操作相关的数据。 而联合体union也是用来组合不同类型的变量,不同于结构体的是,联合体的所有成员变量都共享同一块内存空间。联合体的大小取决于成员变量中占用内存空间最大的数据类型。只能同时使用其中的一个成员变量,存取一个成员变量会覆盖之前存入的值。通过使用联合体,可以节省内存空间,但在数据使用时需要小心,确保不会出现意外的数据覆盖。 总结来说,结构体struct和联合体union的区别是: 1. 结构体允许不同类型的成员变量,而联合体中的成员变量必须是相同的类型。 2. 结构体的成员变量占用不同的内存空间,联合体的成员变量共享同一块内存空间。 3. 结构体的大小等于所有成员变量所占内存空间的总和,联合体的大小等于最大的成员变量所占内存空间。 4. 结构体的所有成员变量可以同时使用,而联合体只能同时使用一个成员变量。 5. 结构体适用于存储和操作不同类型的相关数据,联合体适用于节省内存空间、只需存取其中一个成员变量的情况下。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值