9.1 结构体
1. 什么是结构体
结构体(struct
)是C语言中一种用户自定义的数据类型,它可以将不同类型的变量组合成一个单一的数据类型。结构体在组织复杂数据结构(如数据库记录、树节点等)时非常有用。
定义结构体:
struct 结构体名 {
数据类型 成员名;
数据类型 成员名;
// 更多成员
};
示例:
#include <stdio.h>
// 定义一个表示学生信息的结构体
struct Student {
char name[50];
int age;
float gpa;
};
int main() {
struct Student student1; // 声明结构体变量
// 访问结构体成员并赋值
student1.age = 20;
student1.gpa = 3.8;
snprintf(student1.name, sizeof(student1.name), "John Doe");
// 输出结构体成员
printf("Name: %s\n", student1.name);
printf("Age: %d\n", student1.age);
printf("GPA: %.2f\n", student1.gpa);
return 0;
}
2. 结构体数组
可以声明一个结构体数组来存储多个同类型的结构体变量。
示例:
#include <stdio.h>
struct Student {
char name[50];
int age;
float gpa;
};
int main() {
struct Student students[3]; // 结构体数组
// 初始化结构体数组的元素
snprintf(students[0].name, sizeof(students[0].name), "Alice");
students[0].age = 20;
students[0].gpa = 3.5;
snprintf(students[1].name, sizeof(students[1].name), "Bob");
students[1].age = 22;
students[1].gpa = 3.8;
snprintf(students[2].name, sizeof(students[2].name), "Charlie");
students[2].age = 21;
students[2].gpa = 3.9;
// 输出结构体数组的元素
for (int i = 0; i < 3; i++) {
printf("Student %d: %s, Age: %d, GPA: %.2f\n", i+1, students[i].name, students[i].age, students[i].gpa);
}
return 0;
}
3. 结构体指针
结构体指针用于指向结构体变量。使用->
运算符访问结构体指针指向的结构体成员。
示例:
#include <stdio.h>
struct Student {
char name[50];
int age;
float gpa;
};
int main() {
struct Student student1 = {"John Doe", 20, 3.8};
struct Student *ptr = &student1; // 结构体指针
// 使用结构体指针访问成员
printf("Name: %s\n", ptr->name);
printf("Age: %d\n", ptr->age);
printf("GPA: %.2f\n", ptr->gpa);
return 0;
}
9.2 共用体(联合体)
1. 什么是联合体
联合体(union
)是一种特殊的结构体,它的所有成员共享同一块内存。因此,在一个时间点上,联合体只能存储一个成员的值。联合体在需要节省内存的场景下非常有用。
定义联合体:
union 联合体名 {
数据类型 成员名;
数据类型 成员名;
// 更多成员
};
示例:
#include <stdio.h>
union Data {
int i;
float f;
char str[20];
};
int main() {
union Data data; // 声明联合体变量
data.i = 10; // 设置整型成员
printf("Data as integer: %d\n", data.i);
data.f = 220.5; // 设置浮点型成员
printf("Data as float: %.2f\n", data.f);
snprintf(data.str, sizeof(data.str), "Hello");
printf("Data as string: %s\n", data.str);
// 注意:设置一个成员的值会覆盖其他成员的值,因为它们共享同一块内存
return 0;
}
9.3 枚举类型
枚举类型(enum
)是一种特殊的整型,它的值由标识符列表组成。枚举类型通常用于表示一组相关的常量,如星期几、月份等。
定义枚举类型:
enum 枚举名 {
常量1,
常量2,
// 更多常量
};
示例:
#include <stdio.h>
enum Day {
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
};
int main() {
enum Day today = Wednesday; // 使用枚举类型
printf("Day of the week: %d\n", today); // 输出:2
return 0;
}
9.4 结构体与联合体的比较
内存使用:
- 结构体中的每个成员都有自己的内存空间,因此结构体的大小是所有成员大小的总和。
- 联合体的所有成员共享同一块内存,联合体的大小是其最大成员的大小。
用法:
- 结构体适用于需要同时存储多种不同类型数据的情况。
- 联合体适用于在同一时间点只需要存储一个成员值的情况,可以节省内存。
9.5 结构体与联合体的嵌套
结构体和联合体可以嵌套使用,形成更复杂的数据结构。
示例:
#include <stdio.h>
// 嵌套结构体和联合体
struct Address {
char street[50];
int zipCode;
};
struct Person {
char name[50];
int age;
struct Address address; // 嵌套结构体
};
int main() {
struct Person person1;
// 访问嵌套结构体成员
snprintf(person1.name, sizeof(person1.name), "Alice");
person1.age = 30;
snprintf(person1.address.street, sizeof(person1.address.street), "123 Main St");
person1.address.zipCode = 12345;
printf("Name: %s\n", person1.name);
printf("Age: %d\n", person1.age);
printf("Address: %s, ZIP Code: %d\n", person1.address.street, person1.address.zipCode);
return 0;
}
练习
- 编写一个程序,定义一个结构体来存储学生的姓名、学号和成绩,创建一个学生数组并输出每个学生的信息。
- 定义一个联合体,可以存储整数、浮点数和字符串,编写一个程序演示它的使用。
- 编写一个程序,定义一个枚举类型表示一年中的月份,使用该枚举类型输出指定月份的名称。
- 编写一个程序,使用嵌套结构体存储书籍信息(如书名、作者和出版社地址)并输出这些信息。
完成这些练习后,你将对结构体和联合体有深入的理解。