Menu
CoddyTech

“Self”指针

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

在 Python 或 Java 这类面向对象的语言中,调用 object.method() 时,语言会自动将对象本身传递给方法。在 C 中,我们必须手动完成这一步,将指向结构体的指针作为第一个参数传递。

这个指针通常命名为 self(借自 Python)或 this(来自 C++)。它让函数能够访问结构体的数据,以便读取或修改这些数据:

typedef struct {
    int health;
} Player;

void player_take_damage(Player *self, int amount) {
    self->health -= amount;
}

self 指针使这个函数能够像方法一样工作。它知道要修改哪个玩家。没有它,这个函数就无法访问特定的结构体实例。调用这个函数时,你需要传入结构体的地址:

Player hero = {100};
player_take_damage(&hero, 25);
// hero.health 现在是 75

要修改结构体,必须使用指针,而不是直接传递结构体。如果按值传递结构体,函数收到的会是一个副本,函数返回时所做的任何更改都会丢失。指针可以确保更改保留在原始结构体中。

challenge icon

挑战

简单

我们来构建一个跟踪已过秒数的 Timer 模块。你将练习使用“self”指针模式,通过充当方法的函数来修改结构体的内部状态。

你将创建三个文件:

  • timer.h:声明一个只有一个 int seconds 成员的 Timer 结构体。还要声明两个函数:timer_tick(接收一个指向 Timer 的指针,并增加指定的秒数)和 timer_reset(接收一个指向 Timer 的指针,并将秒数重置为零)。使用符号 TIMER_H 设置包含保护。
  • timer.c:实现这两个函数。timer_tick 函数应接收一个 Timer *self 和一个 int amount,然后将 amount 加到计时器的秒数上。timer_reset 函数应接收一个 Timer *self,并将它的秒数设为零。
  • main.c:创建一个 Timer,对它执行操作,并显示结果。

你将收到两个整数输入:计时器的初始秒数和通过 tick 要增加的秒数。

在主文件中:

  1. 使用初始秒数值初始化一个 Timer
  2. 调用 timer_tick 来增加指定的秒数
  3. 打印当前秒数
  4. 调用 timer_reset 来重置计时器
  5. 再次打印秒数(应为 0)

按照以下格式打印结果:

After tick: {seconds}
After reset: {seconds}

例如,初始值为 30,并增加 15 秒时,输出如下:

After tick: 45
After reset: 0

亲手试试

#include <stdio.h>
#include "timer.h"

int main() {
    int initial_seconds, amount_to_add;
    scanf("%d", &initial_seconds);
    scanf("%d", &amount_to_add);
    
    // TODO:创建一个 Timer,并用 initial_seconds 初始化它
    
    // TODO:调用 timer_tick,增加 amount_to_add 秒
    
    // TODO:按格式 "After tick: {seconds}" 输出当前秒数
    
    // TODO:调用 timer_reset 重置计时器
    
    // TODO:按格式 "After reset: {seconds}" 再次输出秒数
    
    return 0;
}
quiz icon自我测试

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

面向对象编程中的所有课

自己练习: C 在线编译器