【C语言_23】联合(union)和枚举(enum)!

时间:2022-10-13 12:09:09

1.联合(union)

联合体也称共用体,和结构体很像,结构体各成员变量有自己独立的存储位置,而联合的成员变量共享同一片存储区域,因此联合变量再一个时刻只能保存它的某一个成员的值。

(1).联合的定义方式

联合的定义方式与结构体是一样的,只是把关键字 struct 改成 union:

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

(2).联合与结构的区别

我们先用sizeof来测量他们所占空间的大小:

#include<stdio.h>
int main()
{
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));
printf("sizeof char %d\n", sizeof(char));
printf("sizeof short %d\n", sizeof(short));
printf("sizeof long long %d\n", sizeof(long long));
return 0;
}

运行结果:

【C语言_23】联合(union)和枚举(enum)!

按理来说s,u都应该是占有1+2+8=11个字节。

为什么s占用了16个字节,u占用了11个字节。我们来看看下面的代码:

//打印s,u,中的成员地址:
#include<stdio.h>
int main()
{
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", &s.ll);
printf("&u.c %d\n", &u.c);
printf("&u.s %d\n", &u.s);
printf("&u.ll %d\n", &u.ll);
return 0;
}

运行结果:

【C语言_23】联合(union)和枚举(enum)!

根据这个结果我们可以看出:

结构s内存排布情况,这种现象被称为内存对齐:

【C语言_23】联合(union)和枚举(enum)!

联合u中c,s,ll的首地址都为17823788,所以联合的大小为最大成员的大小。


在联合(union)中存储一个值将覆盖掉其他成员的值:

#include<stdio.h>
int main()
{
union {
char c;
short s;
long long ll;
}u;
u.c = 123;
printf("u.c=%d\n", u.c);
u.s = 66;
printf("u.c=%d\n", u.c);
return 0;
}

运行结果:证明了在联合(union)中存储一个值将覆盖掉其他成员的值

【C语言_23】联合(union)和枚举(enum)!

2.联合应用举例

有一种信息,它有三个形态(整数,浮点数,字符串),一次只能出现一种形态.

#include<stdio.h>

struct message {
int type;
union {
int n;
float f;
char* str;
}u;
};
void printmsg(struct message msg)
{
switch (msg.type) {
case 1:
printf("%d\n", msg.u.n);
break;
case 2:
printf("%f\n", msg.u.f);
break;
case 3:
printf("%s\n", msg.u.str);
}
}
int main()
{
struct message msg[3];
msg[0].type = 1;
msg[0].u.n = 123;
msg[1].type = 2;
msg[1].u.f = 3.14159;
msg[2].type = 3;
msg[2].u.str = "hello";
for (int i = 0; i < 3; i++) {
printmsg(msg[i]);
}
return 0;
}

【C语言_23】联合(union)和枚举(enum)!

3.枚举(enum)

枚举是 C 语言中的一种基本数据类型,它可以让数据更简洁,更易读。在实际问题中,有些变量的取值被限定在一个有限的范围内。例如,一个星期内只有七天,一年只有十二个月,一个班每周有六门课程等等。如果把这些量说明为整型,字符型或其它类型显然是不妥当的。为此,C语言提供了一种称为“枚举”的类型。在“枚举”类型的定义中列举出所有可能的取值,被说明为该“枚举”类型的变量取值不能超过定义的范围。

enum enumtype{
Monday,
Tuesday,
Wednesday
Thursday,
Friday,
Saturday,
Sunday,
}weekday;
//成员之间逗号隔开
//Monday,Tuesday等是符号常量

枚举会从0开始依次递增:

#include<stdio.h>
enum msgtype {
eInt,
eFloat,
eString,
};

int main()
{
printf("%d\n", eInt);
printf("%d\n", eFloat);
printf("%d\n", eString);
return 0;
}

【C语言_23】联合(union)和枚举(enum)!

如果想要枚举从1开始:

#include<stdio.h>
enum msgtype {
eInt=1,
eFloat,
eString,
};//可以指定枚举中的每一个成员

int main()
{
printf("%d\n", eInt);
printf("%d\n", eFloat);
printf("%d\n", eString);
return 0;
}

【C语言_23】联合(union)和枚举(enum)!

4.枚举应用举例

#include<stdio.h>
enum msgtype {
eInt,
eFloat,
eString,
};
struct message {
enum msgtype e;
union {
int n;
float f;
char* str;
}u;
};
void printmsg(struct message msg)
{
switch (msg.e) {
case eInt:
printf("%d\n", msg.u.n);
break;
case eFloat:
printf("%f\n", msg.u.f);
break;
case eString:
printf("%s\n", msg.u.str);
}
}
int main()
{
struct message msg[3];
msg[0].e = eInt;
msg[0].u.n = 123;
msg[1].e = eFloat;
msg[1].u.f = 3.14159;
msg[2].e= eString;
msg[2].u.str = "hello";
for (int i = 0; i < 3; i++) {
printmsg(msg[i]);
}
return 0;
}

【C语言_23】联合(union)和枚举(enum)!


持续更新【C语言】系列!有需要的请移步​​秃头程序媛主页​​!