为什么输出与该代码中的预期不同?

时间:2019-05-25 10:44:21

标签: c struct union

我正在研究C结构和联合,因此遇到了这段代码。据我所知,联合工作就像对象,因此,printf应该与 a,b,c,d

#include <stdio.h>

union Type {
    char A[2];
    struct{
        char B;
        char C;
    };
};

int main(){

    Type Data;
    Data.A[0] = 'a';
    Data.A[1] = 'b';
    Data.B = 'c';
    Data.C = 'd';

        printf("%c %c %c %c \n", Data.A[0], Data.A[1], Data.B, Data.C);
    return 0;
}

为什么输出实际上不是a,b,c,d?

1 个答案:

答案 0 :(得分:1)

来自Union type

  

CC++中,未标记的并集的表达几乎完全像   except that each data member begins at the same location in memory

联合的大小是联合的最大元素的大小。就您而言

union Type {
    char A[2];
    struct{
        char B;
        char C;
    };
};

two bytes的总数被分配给整个联合,并且所有成员开始从联合的相同基本起始地址访问数据

这两个陈述时

Data.A[0] = 'a';
Data.A[1] = 'b';

看起来像

      A[0]                  A[1]
 -------------------------------------------
|      'a'         |        'b'            |
 -------------------------------------------
       B                    C   
0x100              0x101
  |
 lets assume 0x100 as base address of union

,如果您访问Data.A[0]Data.B,由于aData.A[0]都从起始地址即{{ 1}}。此外,Data.B0x100的打印效果与从Data.A[1]内存位置访问数据的打印效果相同。

当这两个语句下方

Data.C

执行,看起来像

0x101

现在,如果同时打印Data.B = 'c'; Data.C = 'd'; A[0] A[1] ------------------------------------------------------------------ | 'c' (overwritten 'a') | 'd'(overwritten 'b') | ------------------------------------------------------------------- B C 0x100 0x101 | lets assume 0x100 as base address of union ,它会在Data.A[0]内存位置打印数据,即先前的数据被覆盖时即Data.B。同样,0x100c都打印Data.A[1]