一、定义和用法
结构体(Struct)和联合体(Union)是C语言中同属于复合数据类型的一种类型,两者都可以封装多个不同类型的数据,但是却有着显著的不同之处。
1. 结构体的定义和用法
结构体是一种用户定义的数据类型,它可以用来封装多个不同类型的数据。通常情况下,结构体成员被设计为具有不同的数据类型。结构体通常被用来代表一个数据对象,例如汽车、学生、员工等等。C语言中结构体由多个成员组成,每个成员可以是不同类型的数据。
struct car {
char brand[20];
char model[20];
int year;
float price;
};
上述代码定义了一个名为car的结构体,它包含四个成员,分别是char类型的brand和model、int类型的year和float类型的price。我们可以使用结构体来表示一辆汽车。
2. 联合体的定义和用法
联合体是一种特殊的结构体,它的所有成员共享同一段内存。联合体的所有成员使用同一份内存空间,所以修改其中某一个成员的值,会影响到另一个成员的值。联合体通常被用来节省内存,例如有一些数据只用到其中一个成员。
union data {
int integer;
float decimal;
};
上述代码定义了一个名为data的联合体,它包含了两个成员,一个是int类型的integer,另一个是float类型的decimal,它们占据同一段内存空间。我们可以使用联合体来表示一个数据,可以是一个整数或者是一个浮点数。
二、内存布局
结构体和联合体的内存布局也有着非常大的区别。
1. 结构体的内存布局
结构体的内存布局是将每个成员单独分配内存,并依次排列。每个成员在内存中的地址都是连续的,各成员之间在内存中没有任何关联。
struct car {
char brand[20];
char model[20];
int year;
float price;
};
struct car mycar;
上述代码定义了一个名为mycar的结构体变量。
内存图:
0 20 40 44
+----------+----------------+----------+----------+
| brand | model | year | price |
+----------+----------------+----------+----------+
| |
mycar
在内存中,四个成员按照定义的顺序被依次排列。用sizeof运算符可以计算结构体的大小(单位为字节)。
printf("%zu", sizeof(mycar)); // 输出:44
2. 联合体的内存布局
联合体的内存布局只分配联合体中最大的成员所需要的内存空间,不管其他的成员的大小是多少。每个成员在内存中的地址都是相同的。
union data {
int integer;
float decimal;
};
union data mydata;
上述代码定义了一个名为mydata的联合体变量。
内存图:
0-3 4-7
+-------+
|integer| 4 bytes
+-------+
OR
+-------+
|decimal| 4 bytes
+-------+
mydata
在内存中,union中仅分配了4个字节的空间,不管是integer还是decimal都使用这4个字节,因此,修改一个成员会影响到另外一个成员。
mydata.integer = 12;
printf("%d, %f", mydata.integer, mydata.decimal); // 输出:12, 0.000000
mydata.decimal = 23.45;
printf("%d, %f", mydata.integer, mydata.decimal); // 输出:1093507190, 23.450001
三、应用场景
1. 结构体的应用场景
结构体通常被用来封装多个相关类型的数据,使得这些数据可以统一管理,方便使用。例如,用结构体来表示一个学生信息。
struct student {
char name[20];
int age;
char gender[6];
};
2. 联合体的应用场景
联合体通常被用来在一段内存空间中同时表示多个数据类型,这些数据类型在不同的时间和场合下只有一个会被使用。例如,用联合体来表示数据类型转换。
union data {
int integer;
float decimal;
};
void swap(union data *a, union data *b) {
union data temp = *a;
*a = *b;
*b = temp;
}
union data d1, d2;
d1.integer = 12345;
d2.decimal = 67.89;
swap(&d1, &d2);
printf("%d, %f", d1.integer, d2.decimal); // 输出:1090873190, 12345.000000
四、小结
结构体和联合体是C语言中的两种复合数据类型,结构体将多个不同类型的成员按顺序排列在一起,并分配不同的内存空间;联合体将多个数据类型的成员共享同一段内存,以节省内存空间。两者在应用场景上也有所不同,需要根据实际需求选择使用。