Skip to content

LV105-共用体大小

一、联合体大小计算规则

1. 成员的数据类型都相同

联合体占用空间大小=任一成员数据类型大小。

2. 成员的数据类型不相同

类型不相同的时候,分两种情况:

  • 没有定义 #pragma pack(value) :联合体中最大成员所占内存的大小且必须为最大数据类型所占字节的最小倍数

  • 定义了 #pragma pack(value) :联合体中最大成员所占字节数必须为 value 的最小倍数。

3. 特殊的联合体

对于一个没有任何成员的联合体,在 C 中占用空间为 0 。

二、实例分析

1. 成员相同的联合体

c
#include <stdio.h>
union
{
	char a;
	char b;
} S1;

int main(int argc, char *argv[])
{
	printf("sizeof(S1)    =%2ld, addr=%p\n",sizeof(S1), &S1);
	printf("sizeof(S1.a)  =%2ld, addr=%p\n",sizeof(S1.a), &S1.a);
	return 0;
}

在终端执行以下命令编译程序:

shell
gcc test.c -Wall # 生成可执行文件 a.out 
./a.out # 执行可执行程序

然后,终端会有以下信息显示:

shell
sizeof(S1)    = 1, addr=0x564129368011
sizeof(S1.a)  = 1, addr=0x564129368011

2. 特殊联合体

c
#include <stdio.h>
union
{
} S1;

int main(int argc, char *argv[])
{
	printf("sizeof(S1)    =%2ld, addr=%p\n",sizeof(S1), &S1);
	return 0;
}

在终端执行以下命令编译程序:

shell
gcc test.c -Wall # 生成可执行文件 a.out 
./a.out # 执行可执行程序

然后,终端会有以下信息显示:

shell
sizeof(S1)    = 0, addr=0x564c0595f011

3. 成员不同的联合体

3.1 实例1

c
#include <stdio.h>
union
{
	char a;
	double b;
	char c[9];
} S1;

int main(int argc, char *argv[])
{
	printf("sizeof(S1)    =%2ld, addr=%p\n",sizeof(S1), &S1);
	printf("sizeof(S1.a)  =%2ld, addr=%p\n",sizeof(S1.a), &S1.a);
	printf("sizeof(S1.b)  =%2ld, addr=%p\n",sizeof(S1.b), &S1.b);
	printf("sizeof(S1.c)  =%2ld, addr=%p\n",sizeof(S1.c), &S1.c);
	return 0;
}

在终端执行以下命令编译程序:

shell
gcc test.c -Wall # 生成可执行文件 a.out 
./a.out # 执行可执行程序

然后,终端会有以下信息显示:

shell
sizeof(S1)    =16, addr=0x556b80767020
sizeof(S1.a)  = 1, addr=0x556b80767020
sizeof(S1.b)  = 8, addr=0x556b80767020
sizeof(S1.c)  = 9, addr=0x556b80767020

3.2 实例2

该实例使用了 __attribute__机制,设置了 __packed__属性。

c
#include <stdio.h>
union __attribute__((__packed__))
{
	char a;
	double b;
	char c[9];
} S1;

int main(int argc, char *argv[])
{
	printf("sizeof(S1)    =%2ld, addr=%p\n",sizeof(S1), &S1);
	printf("sizeof(S1.a)  =%2ld, addr=%p\n",sizeof(S1.a), &S1.a);
	printf("sizeof(S1.b)  =%2ld, addr=%p\n",sizeof(S1.b), &S1.b);
	printf("sizeof(S1.c)  =%2ld, addr=%p\n",sizeof(S1.c), &S1.c);
	return 0;
}

在终端执行以下命令编译程序:

shell
gcc test.c -Wall # 生成可执行文件 a.out 
./a.out # 执行可执行程序

然后,终端会有以下信息显示:

shell
sizeof(S1)    = 9, addr=0x5611cb03e018
sizeof(S1.a)  = 1, addr=0x5611cb03e018
sizeof(S1.b)  = 8, addr=0x5611cb03e018
sizeof(S1.c)  = 9, addr=0x5611cb03e018