访问父类成员
本课属于 Coddy C 学习旅程的“面向对象编程”单元。第 30 课,共 61 课。
现在我们已经了解了结构体嵌入和首个成员规则,接下来重点看看实际应用:如何在函数中读取和修改嵌入的父级数据。
函数接收 Child 结构体(或指向它的指针)时,访问父级的成员需要通过嵌入的结构体进行访问。语法取决于你使用的是值还是指针。
typedef struct {
int id;
int score;
} Parent;
typedef struct {
Parent parent;
char grade;
} Child;有了指向 Child 的指针,先使用箭头运算符访问父级,再使用点运算符访问其成员:
void update_score(Child* c, int new_score) {
c->parent.score = new_score; // 先用箭头运算符,再用点运算符
}
void print_info(Child* c) {
printf("ID: %d, Score: %d\n", c->parent.id, c->parent.score);
}对于值(通过复制传递),全程使用点号:
void show_id(Child c) {
printf("ID: %d\n", c.parent.id); // 先用点号,再用点号
}这种链式访问模式,child->parent.member 或 child.parent.member,是在 C 的组合模型中访问继承数据的方式。它比真正的继承稍微冗长一些,但能明确清楚地表达类型之间的关系。
挑战
简单让我们构建一个学生评分系统,演示如何访问和修改嵌入式结构体中的数据。你将创建一个层级结构,其中 Student 包含一个嵌入式的 Person,然后编写一些函数,通过子结构体处理父结构体的数据。
你需要将代码分成三个文件:
student.h:定义带有包含保护的结构体层级。创建一个Person结构体,其中包含name(一个长度为 50 个字符的字符数组)和age(一个整数)。然后定义一个Student结构体,将Person作为第一个成员嵌入其中,并添加一个grade字段(一个表示分数的整数)。声明两个函数:set_person_age接收一个Student*和一个新的年龄值;print_student接收一个Student*并显示所有信息。student.c:实现这两个函数。你的set_person_age函数应修改嵌入式Person结构体中的年龄。在这里,你将练习箭头运算符后接点运算符的语法(s->person.age)。你的print_student函数应访问并显示嵌入式 Person 和 Student 自身的所有字段。main.c:创建一个Student变量并初始化它的所有字段。然后使用set_person_age更新嵌入式 Person 的年龄,并调用print_student显示结果。
你将收到四个输入:学生的姓名(一个字符串)、初始年龄(一个整数)、成绩(一个整数),以及新年龄(一个要通过你的函数更新的整数)。
在主文件中,使用初始值创建学生,然后调用 set_person_age 将年龄改为新值,最后调用 print_student 显示更新后的信息。
你的输出应如下所示:
Name: Emma
Age: 21
Grade: 85其中,Emma 是姓名,21 是更新后的年龄(不是初始年龄),85 是成绩。这里的重点是学习如何通过嵌入式结构体访问父结构体的成员,以读取和写入数据。
亲手试试
#include <stdio.h>
#include <string.h>
#include "student.h"
int main() {
char name[50];
int initial_age, grade, new_age;
// 读取输入
fgets(name, 50, stdin);
name[strcspn(name, "\n")] = '\0'; // 移除换行符
scanf("%d", &initial_age);
scanf("%d", &grade);
scanf("%d", &new_age);
// TODO: 创建一个 Student 变量
// TODO: 初始化 student 的所有字段
// 用 strcpy 将 name 复制到内嵌的 person 的 name 字段
// 将内嵌的 person 的 age 字段设置为 initial_age
// 设置 student 的 grade 字段
// TODO: 调用 set_person_age,将 age 更新为 new_age
// TODO: 调用 print_student 显示结果
return 0;
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: C 在线编译器