1.2 struct和class与union空间分配union_马鸿凯_新浪博客

在进行空间分配计算的时候明白决定一个类型空间大小的原因:
其实一般都会黏贴上这样一张图:
1.2 <wbr>struct和class与union空间分配union
其实还差一个long long 类型:  8 个
但是以上皆基于一个点: 32位平台...
决定数据大小原因:
cpu  开发平台(比如我用VS2013) os (操作系统多少位)
这三个以最低标准决定数据类型的大小.
接下来就来看看空间分配放入问题:

部分来源于下文此文  C语言union关键字
1  union简介
      在union 中所有的数据成员共用一个空间,同一时间只能储存其中一个数据成员,所有的数据成员具有相同的起始地址. union的大小即是union里面最大数据成员的大小.   在C 1.2 <wbr>struct和class与union空间分配union 里,union 的成员默认属性页为public。union 主要用来压缩空间。如果一些数据不可能在同一时间同时被用到,则可以使用union。
例如:
union StateMachine
{
   char character;
   int number;
   char *str;
   double exp;
};
大小为:double的大小8;

union StateMachine
{
   char character;
   char arry[12]; // 或者改为 char arry[9]
   int number;
   char *str;
   double exp;
}; 
大小为皆为 16

一、大小端模式对union 类型数据的影响

下面再看一个例子:
union
{
   int i;
   char a[2];
}*p, u;
p =&u;
p->a[0] = 0x39;
p->a[1] = 0x38;

p.i 的值应该为多少呢?

这里需要考虑存储模式:大端模式和小端模式。
  1. 大端模式(Big_endian):字数据的高字节存储在低地址中,而字数据的低字节则存放在高地址中。
  2. 小端模式(Little_endian):字数据的高字节存储在高地址中,而字数据的低字节则存放在低地址中。
union 型数据所占的空间等于其最大的成员所占的空间。对union 型的成员的存取都是相对于该联合体基地址的偏移量为0 处开始,也就是联合体的访问不论对哪个变量的存取都是从union 的首地址位置开始。如此一解释,上面的问题是否已经有了答案呢?

Big_endian:    3839
Little_endian: 3938

二、如何用程序确认当前系统的存储模式?

1.2 <wbr>struct和class与union空间分配union
可以看到 39 (低位)在低地址 38 (高位)在高地址 -> 小端存储

上述问题似乎还比较简单,那来个有技术含量的:请写一个C 函数,若处理器是Big_endian 的,则返回0;若是Little_endian 的,则返回1。

先分析一下,按照上面关于大小端模式的定义,假设int 类型变量i 被初始化为1。

以大端模式存储,其内存布局如下图:
以小端模式存储,其内存布局如下图:
变量i 占4 个字节,但只有一个字节的值为1,另外三个字节的值都为0。如果取出低地址上的值为0,毫无疑问,这是大端模式;如果取出低地址上的值为1,毫无疑问,这是小端模式。既然如此,我们完全可以利用union 类型数据的特点:所有成员的起始地址一致。

到现在,应该知道怎么写了吧?参考答案如下:
int checkSystem( )
{
   union check
   {
      int i;
      char ch;
   } c;
   c.i = 1;
   return (c.ch ==1);
}
 //  因为返回时地址地址,如果c,ch是1 则,返回为1 是小端存储,反之亦然

现在你可以用这个函数来测试你当前系统的存储模式了。当然你也可以不用函数而直接去查看内存来确定当前系统的存储模式。如下图:
图中0x01 的值存在低地址上,说明当前系统为小端模式。



union的对其规则:
①联合就是一个结构,
②它的所有成员相对于基地址的偏移量都为0,
③此结构空间要大到足够容纳最“宽”的成员
④并且,其对齐方式要适合于联合中所有类型的成员。

例如:

union StateMachine
{
   char character;
   char arry[12]; // 或者改为 char arry[9]
   int number;
   char *str;
   double exp;
}; 
该结构要放得下int i[5]必须要至少占12个字节。如果没有double的话12个字节够用了,此时按4字节对齐。但是加入了double就必须考虑double的对齐方式,double是按照8字节对齐的,所以必须添加4个字节使其满足8×2=16,也就是必须也是8的倍数,这样一来就出来了4这个数字。综上所述,最终联合体的最小的size也要是所包含的所有类型的基本长度的最小公倍数才行。(这里的字节数均指winnt下的值,平台、编译器不同值也有可能不同。)

typedef long Align;

union header {
    struct {
        union header *ptr;
        unsigned size;
    } s;
    Align x;
}

这里的Align有什么用?作用只有一个,就是强迫分配的结构体按long的长度对齐

答案: 8

指定对其方式:pragma pack()

详见:

指定对其规则

例如:  

#pragma pack (2)

union StateMachine

{

   char character;

   int number;

   char arry[9];

   char *str;

   double exp;

};

#pragma pack

结果:10

#pragma pack (1)

union StateMachine

{

   char character;

   int number;

   char arry[9];

   char *str;

   double exp;

};

#pragma pack

结果:9

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ma_Hong_Kai

微信 2936729162

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值