10-3. 联合与枚举

  • 学习人数 30K+
  • 适合所有人群学习
avatar
林耿亮

你好编程主讲老师

1.联合与结构

上一节中我们使用struct关键词,组合不同的类型让它们成为一个新的类型。

例如,我们想组合charshortlong long,可以像如下代码写法。

struct {
    char c;
    short s;
    long long ll;
}s;

对于结构struct的讨论在上一节已经够多了。在一节中,我们讨论和结构语法类似的联合,关键词为union

联合charshortlong long,可以像如下代码写法。

union {
    char c;
    short s;
    long long ll;
}u;

联合的语法非常类似于结构的语法,几乎仅仅换了一个关键词而已。让我们来看看,它们之间有什么差别?

我们先使用sizeof分别测试一下它们的大小。

struct {
    char c;
    short s;
    long long ll;
}s;

union {
    char c;
    short s;
    long long ll;
}u;

printf("sizeof s %d\n", sizeof(s));
printf("sizeof u %d\n", sizeof(u));

struct与union的大小

结构s测得大小为16,而联合u测得大小为8。

对于结构来说,char占用1字节,short占用2个字节。long long占用8字节。如果它们相邻紧密排列,按理说会占用11个字节。

按理说占用11个字节

似乎两个结果都有些奇怪。让我们将其成员的地址打印出来,详细地分析一下,它们的内存排布情况。

struct {
    char c;
    short s;
    long long ll;
}s;

union {
    char c;
    short s;
    long long ll;
}u;

printf("&s.c %d \n", &s.c);
printf("&s.s %d \n", &s.s);
printf("&s.ll %d \n\n", &s.ll);
printf("&u.c %d \n", &u.c);
printf("&u.s %d \n", &u.s);
printf("&u.ll %d \n", &u.ll);

成员内存地址

结构s的成员c的首地址为8649904。 结构s的成员s的首地址为8649906。 结构s的成员ll的首地址为8649912。

结构的内存分布

根据地址,我们画出了结构s各个成员的内存排布情况。charshort只留空了一个字节,而shortlong long之间留空了4个字节。

这种现象被称为内存对齐,虽然会浪费一些内存空间,对齐后的数据能够被更快的访问。

内存对齐有一套规则,这里我们并不展开讨论结构中的成员是如何对齐的了。我们接着往下看,看看联合中的成员的内存排布情况。

联合u的成员c的首地址为8649896。 联合u的成员s的首地址为8649896。 联合u的成员ll的首地址为8649896。

似乎联合中成员的首地址是重叠的。

首地址重叠

没错,联合中的成员首地址是重叠的,这意味着联合的大小为联合中最大成员的大小。

接下来,我们进一步研究联合的性质。