结构体把多个相关值组合成一个对象。每个成员拥有独立存储,可以同时保存不同类型的数据。使用点运算符访问结构体对象的成员。
#include <stdio.h>
struct Student {
char name[32];
int score;
double attendance;
};
int main(void) {
struct Student student = {"Maya", 88, 0.96};
printf("%s: %d, %.0f%%\n",
student.name,
student.score,
student.attendance * 100.0);
return 0;
}成员按声明顺序出现在结构体中,但实现可能在成员之间或末尾加入填充字节以满足对齐要求。因此不要手算偏移;需要大小时使用 sizeof。
一个对象中的独立成员
外框表示一个完整的 student 变量。修改其中一个成员,观察同一对象里的其他成员仍保留各自的数据。
三个值同时保存在 student 内。点击任意一条语句,只有对应成员的区域会高亮并改变。
与联合体不同,这些区域不重叠。图中宽度不代表字节比例,未展开 name 的 32 个字符位置,也省略了可能的对齐填充;实际总大小使用 sizeof(student) 查询。strcpy 需包含 <string.h>,这里使用的姓名都能放进 name 数组。结构体数组
结构体类型可以作为数组元素类型。每个数组元素都是完整、独立的 Student 对象,可使用 students[i].score 访问成员。
#include <stdio.h>
struct Student {
char name[32];
int score;
double attendance;
};
int main(void) {
struct Student students[] = {
{"Maya", 88, 0.96},
{"Noah", 93, 0.91},
{"Iris", 85, 0.98}
};
int count = (int) (sizeof(students) / sizeof(students[0]));
for (int i = 0; i < count; i++) {
printf("%s %d\n", students[i].name, students[i].score);
}
return 0;
}通过指针传递结构体
按值传递结构体会复制整个对象。把地址传给函数可避免复制,并允许函数修改原对象。对于结构体指针,student->score 等价于 (*student).score。
#include <stdio.h>
struct Student {
char name[32];
int score;
double attendance;
};
void add_bonus(struct Student *student, int points) {
if (student != NULL) {
student->score += points;
}
}
int main(void) {
struct Student student = {"Maya", 88, 0.96};
add_bonus(&student, 5);
printf("%d\n", student.score);
return 0;
}知识测验
知识测验
知识测验
定义并打印一本书
定义 Book,包含 char title[40]、int pages、double price。创建值为 “C Handbook”、320、39.90 的对象,并输出 C Handbook | 320 pages | $39.90。
- 声明包含 title、author 和 price 的 Book。
- 初始化一个 Book 变量,确保字符数组容量足够。
- 使用点运算符读取每个成员并格式化输出价格。
找出最高分学生
定义只含 name 和 score 的 Student。实现 const struct Student *top_student(const struct Student *students, int count),返回最高分元素的地址;count 小于等于 0 时返回 NULL。用三名学生测试。
- 定义包含 name 与 score 的 Student。
- 用第一个学生初始化最佳下标。
- 遍历剩余元素并在发现更高分时更新下标,最后输出对应成员。
通过指针更新库存
定义 Product,包含 name 和 stock。实现 int sell(struct Product *product, int amount):指针为 NULL、amount 非正数或库存不足时返回 0;否则减少库存并返回 1。用库存 8 连续销售 3 和 6 件,最后输出库存 5。
- 定义包含商品名和 quantity 的 Inventory。
- 函数先检查指针与 amount 参数。
- 使用 -> 修改原对象的 quantity,并返回操作状态。