在 C 语言编程中,结构体(struct
)、共用体(union
)与枚举(enum
)是三种非常重要的用户自定义数据类型。它们能帮助我们更好地组织、管理和表达复杂的数据结构。本文将结合实例,深入介绍它们的概念、用法以及注意事项。
一、结构体(struct)
1. 什么是结构体
结构体是 C 语言提供的一种 用户自定义数据类型,它允许我们将不同类型的数据组合在一起,从而描述复杂的实体,例如学生、老师、网络协议等。
特点:
可以包含不同类型的成员变量
成员之间在内存中独立存在
可定义为变量、数组、指针、函数参数或返回值类型
示例:
struct student {int sno; // 学号char name[20]; // 姓名float score; // 成绩char sex; // 性别
};
2. 定义与使用
结构体有多种定义形式:
形式1:
struct demo {int a;float b;
};
struct demo d; // 定义变量
形式2:
struct demo {int a;float b;
} d = {1, 3.14};
形式3(一次性结构体):
struct {int a;float b;
} d = {1, 3.14};
3. 成员访问
.
运算符:结构体变量访问成员->
运算符:结构体指针访问成员
struct student s1 = {1001, "Tom", 95.5, 'M'};
printf("%s\n", s1.name); // .
struct student *p = &s1;
printf("%s\n", p->name); // ->
4. 初始化与赋值
初始化需按成员顺序
相同类型的结构体变量可直接赋值
成员变量赋值需按其本身的类型方式
struct student s1 = {1001, "Tom", 95.5, 'M'};
struct student s2;
s2 = s1; // 整体赋值
5. 结构体作为函数参数
可传递结构体变量(不推荐,开销大)
推荐传递结构体指针(效率高)
void printStudent(struct student *p) {printf("%d %s %.2f %c\n", p->sno, p->name, p->score, p->sex);
}
6. 内存对齐
结构体在内存中会进行 自然边界对齐:
每个成员变量按其类型大小对齐
整个结构体的大小按最大成员的对齐数对齐
示例:
struct demo1 {char a; // 1字节char b; // 1字节int c; // 4字节
}; // 占 8 字节struct demo2 {char a; // 1字节int b; // 4字节char c; // 1字节
}; // 占 12 字节
二、共用体(union)
1. 概念
共用体是一种特殊的自定义类型,它的 所有成员共用同一段内存空间。节省空间,但同一时间只能存储一个成员的值。
union demo {char a;short b;int c;
};
特点:
大小由最大成员决定
所有成员起始地址相同
最后一次赋值会覆盖之前的数据
应用示例:
检测大小端
数据协议解析
三、枚举(enum)
1. 概念
枚举用于表示一组有限的常量值,增强代码可读性与类型检查。
enum Weekday {MON, TUE, WED, THU, FRI, SAT, SUN
};
默认从 0 开始递增
本质是
int
类型相比
#define
,枚举有类型检查,更安全
四、综合应用案例
人员信息结构:
struct member {int no;char name[10];union {float score;float salary;} data;
};struct member stu = {119, "Tom", 98.5};
printf("no = %d\n", stu.no);
printf("name = %s\n", stu.name);
printf("score = %f\n", stu.data.score);
总结
结构体:描述复杂实体,适用于多类型组合存储
共用体:节省内存,适用于互斥存储场景
枚举:提高可读性与类型安全
在实际开发中,结构体、共用体和枚举往往配合使用,例如在网络协议解析、设备驱动、嵌入式开发中,能大幅提高程序的可维护性与可扩展性。