美文网首页
union联合体与内存对齐

union联合体与内存对齐

作者: RainingMan | 来源:发表于2017-03-19 18:31 被阅读0次

本文为摘抄并修改,原文:http://www.cnblogs.com/dolphin0520/archive/2011/10/03/2198493.html
联合体例子:

union U
{
    char s[9];
    int n;
    double d;
};

s占9字节,n占4字节,d占8字节,因此sizeof(U)至少9字节。然而用运算符sizeof测试其大小为16。这是因为字节对齐,9既不能被4整除,也不能被8整除。因此补充字节到16,这样就符合所有成员的自身对齐了。
从这里可以看出联合体所占的空间不仅取决于最宽成员,还跟所有成员有关系。即其大小必须满足两个条件:

  • 1)大小足够容纳最宽的成员;
  • 2)大小能被其包含的所有基本数据类型的大小所整除。
#include <stdlib.h>
#include <stdio.h>

union U1
{
    char s[9];
    int n;
    double d;
};

union U2
{
    char s[5];
    int n;
    double d;
};

int main(int argc, char *argv[])
{
    union  U1 u1;
    union U2 u2;
    printf("%ld\n",sizeof(u1));
    printf("%ld\n",sizeof(u2));
    printf("0x%p\n",&u1);
    printf("0x%p\n",&u1.s);
    printf("0x%p\n",&u1.n);
    printf("0x%p\n",&u1.d);
    u1.n=1;
    printf("%d\n",u1.s[0]);
    printf("%lf\n",u1.d);
    
    u1.n=97;
    printf("%c\n",u1.s[0]);
    return 0;
}
cloud@cloud:/web/code/c$ ./union 
16
8
0x0x7ffffdc698a0
0x0x7ffffdc698a0
0x0x7ffffdc698a0
0x0x7ffffdc698a0
1
0.000000
a

对于sizeof(u1)=16。因为u1中s占9字节,n占4字节,d占8字节,因此至少需要9字节。其包含的基本数据类型为char,int,double分别占1,4,8字节,为了使u1所占空间的大小能被1,4,8整除,则需填充字节以到16,因此sizeof(u1)=16.

对于sizeof(u2)=8。因为u2中s占5字节,n占4字节,d占8字节,因此至少需要8字节。其包含的基本数据类型为char,int,double分别占1,4,8字节,为了使u2所占空间的大小能被1,4,8整除,不需填充字节,因为8本身就能满足要求。因此sizeof(u2)=8。

从打印出的每个成员的基地址可以看出,联合体中每个成员的基地址都相同,等于联合体变量的首地址。

对u1.n=1,将u1的n赋值为1后,则该段内存的前4个字节存储的数据为00000001 00000000 00000000 00000000

因此取s[0]的数据表示取第一个单元的数据,其整型值为1,所以打印出的结果为1.

至于打印出的d为0.000000愿意如下。由于已知该段内存前4字节的单元存储的数据为00000001 00000000 00000000 00000000,从上面打印结果48,204,64,0可以知道后面4个字节单元中的数据为00110000 11001100 01000000 00000000,因此其表示的二进 制浮点数为

00000000 01000000 11001100 00110000 00000000 00000000 00000000 00000001

对于double型数据,第63位0为符号位,62-52 00000000100为阶码,0000 11001100 00110000 00000000 00000000 00000000 00000001为尾数,根据其值知道尾数值约为0,而阶码为4-1023=-1019,因此其表示的浮点数为1.0*2^(-1019)=0.00000000000......,因此输出结果为0.000000。

至于

u1.n=97;
printf("%c\n",u1.s[0]);
return 0;

我这里写入的是4字节的int型数据97;
却以字符串格式来打印,打印出ascii对应97的字母a。

为什么要内存对齐?
http://www.jianshu.com/p/0355f83ff557

相关文章

  • iOS 内存对齐

    一、结构体内存对齐 1.1 结构体内存对齐三大原则 数据成员对⻬规则结构体(struct)或联合体(union)的...

  • union联合体与内存对齐

    本文为摘抄并修改,原文:http://www.cnblogs.com/dolphin0520/archive/20...

  • oc中对象的内存对齐方式初探

    内存对齐规则 1:数据成员对⻬规则:结构(struct)(或联合体(union))的数据成员,第一个数据成员放在o...

  • 02--对象本质02--isa本质

    [TOC] 一、联合体 Union 1.1 联合体的特性 联合体 union 也成共用体,有以下特性: union...

  • union

    Union 称为共用体,或联合体类型。union可以装入不同类型的变量,这些成员共享一段内存,可以用于节省内存。其...

  • iOS底层探索-calloc

    一、calloc底层探索 1.1、内存对齐原则 a:数据成员对齐规则:结构(struct)(或联合(union))...

  • 2018-08-27 C语言union 联合体 复习

    1.联合体union的基本特性——和struct的同与不同 union,中文名“联合体、共用体”,在某种程度上类似...

  • NDK启航篇——C语言基础(联合体)

    今天写一下联合体union(比较简单)。 什么是联合体? 不同类型的变量,共同占一段内存(相互覆盖),联合体变量任...

  • 从结构体内存对齐到OC对象内存对齐

    1、结构体内存对齐 结构体对齐规则:1:数据成员对⻬规则:结构(struct)(或联合(union))的数据成员,...

  • (二) 内存对齐

    内存对齐规则 1: 数据成员对齐规则: 结构(struct) (或联合(union))的数据成员, 第一个数据成员...

网友评论

      本文标题:union联合体与内存对齐

      本文链接:https://www.haomeiwen.com/subject/eqgmnttx.html