结构体的定义方式


结构体数组


给结构体起别名


使用案例:


结构体作为函数的参数进行传递
下面的代码还有一个定义结构体的代码,这里就不展示了
要用typedef起个别名为s,里面的属性是name和age,name用字符串

注意我们在下图使用指针p接收的地址,因此我们在上图要传入地址,这里没有写出来,也就是第四步method(&stu);

结构体嵌套
这里补充一个课外知识点:在C语言代码文件中,头文件引用的顺序是:被引用的头文件放在最上方,引用其他文件的头文件放在下方。对于结构体的位置安排,所有结构体定义应置于函数声明之前。函数声明之后是主函数,而各个函数的具体实现则放在主函数之后。




综合练习-投票选举

第一步先定义一个景点的结构体包含了景点的名称和景点被投票的次数


很多人可能会疑惑,这里其实省略了很多定义步骤。具体来说:
-
对于一个结构体类型的变量数组,他直接进行了赋值操作。我们可以将整个数组视为一个类型,然后对这个类型数组进行赋值。这里用逗号分隔时省略了换行,如果换成多行显示会更清晰。
-
还有一个隐藏知识点:他同时对数组内结构体变量的属性进行了批量赋值。如果是int类型,我们只需赋一个值;但这里是结构体,所以采用了批量赋值的方式。

随后就是找最大值的算法

内存对齐:

在c语言结构体中,我们结构体所占的字节跟我们预想的会有一些不一样,结构体里的变量所占字节是不会挤在一起的。

如图所示,我们的变量a占用8个字节(0-7字节)。char类型的变量b占用1个字节,可以放在第8个字节的位置。int类型的变量c需要4个字节,因此只能从第12个字节开始存放,导致8-11字节成为填充字节。接着char类型的变量d放在第16个字节。由于结构体总大小必须是最大成员类型(double类型)的整数倍(即8的倍数),最终需要18个字节存储,这样整个结构体的内存布局和总大小就确定了。
共同体
属性可能存在多种类型,这种情况可以通过共同体来具体说明。

定义方式和结构体一样,使用方法也和结构体一样

和结构体一样,也可以用typedef来给结构体起别名

共同体的特点

对于第二条:
2️⃣ 所有的变量都使用同一个内存空间
在 union 中,所有成员变量共用同一块内存地址。
无论访问哪个成员,实际上访问的都是相同的内存区域。
cpp
#include <stdio.h>
union Data {
int i;
float f;
char c;
};
int main() {
union Data data;
data.i = 100;
printf("i = %d\n", data.i);
data.f = 3.14;
printf("f = %.2f\n", data.f);
data.c = 'A';
printf("c = %c\n", data.c);
// 打印三个成员的地址
printf("地址:i=%p, f=%p, c=%p\n", &data.i, &data.f, &data.c);
return 0;
}
🔍运行结果分析:
-
i,f,c的地址是相同的。 -
最后赋值的
data.c = 'A'会覆盖之前的内容。由于他们仨占用的一块内存,因此后面写的会覆盖前面写的,最后打印的是data.c的内容
3️⃣ 所占内存大小 = 最大成员的长度(也受内存对齐影响)
共同体分配的内存大小等于最大成员的长度 (再考虑内存对齐)。
例如,一个成员是 int(4字节),另一个是 double(8字节),则整个 union 占用8字节。
这个记住就好,没什么可讲的,就是这个共同体的占用内存和我们最大的成员长度相同
4️⃣ 每次只能给一个变量赋值,第二次赋值会覆盖原有数据
结构体和共同体的区别
我们学完之后发现结构体和共同体存在很多区别


结构体和共同体的用途不同
结构体是一个事物存在多种属性,我们利用结构体
而共同体是一个事物的一个属性存在多种类型,我们用共同体