Menu
CoddyTech

结构体嵌入

本课属于 Coddy C 学习旅程的“面向对象编程”单元。第 28 课,共 61 课。

在 C++ 或 Java 这类面向对象的语言中,继承允许一个类从父类获取属性。C 没有内置的继承功能,但我们可以用一种叫作组合的技术来模拟继承:把一个结构体放进另一个结构体中。

这个想法很简单:如果 Child 需要 Parent 的所有属性,我们就将 Parent 结构体嵌入为 Child 的成员。

typedef struct {
    int id;
    char name[50];
} Parent;

typedef struct {
    Parent parent;  // 嵌入的结构体
    int grade;
} Child;

这里,Child 包含 Parent 拥有的所有内容,还包含它自己的 grade 字段。这就是组合:子类“拥有”一个父类,而不是“是”一个父类,但效果与继承类似。

要通过子实例访问父级成员,你需要使用两次点运算符:

Child c;
c.parent.id = 101;
c.parent.name[0] = 'A';
c.grade = 5;

这种模式构成了在 C 中构建类型层次结构的基础。通过将基结构体嵌入为第一个成员,我们可以使用强大的技术,并将在接下来的课程中探索这些技术。

challenge icon

挑战

简单

让我们来构建一个简单的员工管理系统,演示结构体嵌入:这是 C 中继承的基础。

你将创建一个层级结构,其中 Employee 包含一个 Person。这反映了继承的工作方式:员工“是一个”人,并且有额外的工作相关信息。将 Person 结构体嵌入 Employee 结构体后,你就能获得这个人的所有属性,以及员工特有的字段。

你将把代码组织在三个文件中:

  • types.h:在这里定义两个结构体,并添加包含保护。首先,创建一个 Person 结构体,包含两个字段:name(一个长度为 50 的字符数组)和 age(一个整数)。然后定义一个 Employee 结构体,将 Person 作为第一个成员嵌入其中,并添加一个 employee_id 字段(一个整数)。
  • types.c:实现一个名为 print_employee 的函数,它接收一个指向 Employee 的指针,并打印员工信息。使用你学过的点号和箭头链式语法访问嵌入的人物数据。
  • main.c:创建一个 Employee 变量,为它的所有字段赋值(包括嵌入的人物姓名和年龄),然后使用你的打印函数显示信息。

你将收到三个输入:员工的姓名(一个字符串)、年龄(一个整数)和员工 ID(一个整数)。

你的 print_employee 函数应按以下格式输出员工信息:

Employee: Alice
Age: 28
ID: 1001

其中,Alice 是姓名,28 是年龄,1001 是输入中的员工 ID。

记得通过父成员访问嵌入结构体的成员。例如,要访问姓名,你需要先通过 person 成员进行访问。

亲手试试

#include <stdio.h>
#include <string.h>
#include "types.h"

int main() {
    // 读取输入
    char name[50];
    int age;
    int employee_id;
    
    fgets(name, 50, stdin);
    name[strcspn(name, "\n")] = '\0';  // 移除换行符
    scanf("%d", &age);
    scanf("%d", &employee_id);
    
    // TODO:创建一个 Employee 变量
    
    // TODO:填写嵌入的 person 的姓名和年龄
    // 提示:用 strcpy 复制姓名,通过 employee.person.name 访问
    
    // TODO:设置 employee_id
    
    // TODO:传入指向你的 employee 的指针,调用 print_employee
    
    return 0;
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: C 在线编译器