Menu
CoddyTech

事件系统

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

challenge icon

挑战

简单

让我们构建一个通知系统:这是一种事件驱动架构,多个处理器可以订阅一个事件,并在事件触发时作出响应。这种模式是响应式编程和 GUI 框架的基础。

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

  • event.h:定义 Handler 函数指针类型,它接收一条 const char* 消息。创建一个 Event 结构体,其中包含一个最多可容纳 5 个处理器的数组,以及已注册处理器的数量。声明用于初始化事件、订阅处理器和触发事件以通知所有订阅者的函数。
  • event.c:实现你的事件系统:
    • init_event:接收一个 Event 指针,并将处理器数量设为 0
    • subscribe:接收一个 Event 指针和一个 Handler,如果数组有空位(数量小于 5),就将处理器添加到数组中,并增加数量
    • fire:接收一个 Event 指针和一条消息字符串,然后按订阅顺序,使用这条消息调用每个已注册的处理器
  • main.c:创建三个不同的处理器函数,让它们以各自独特的方式响应事件:
    • logger:打印 [LOG] ,后面跟着消息
    • alert:打印 [ALERT] ,后面跟着消息
    • counter:使用静态变量记录它被调用的次数,然后打印 [COUNT] X,其中 X 是当前计数
    读取一个整数,表示要订阅多少个处理器(1、2 或 3)。按顺序订阅相应数量的处理器:先订阅 logger,然后订阅 alert(如果数量大于等于 2),最后订阅 counter(如果数量为 3)。读取一条消息字符串,然后使用这条消息触发事件。

你的程序将接收:

  1. 要订阅的处理器数量(1、2 或 3)
  2. 要广播的消息

输入分别为 3 和 System started 时的输出示例:

[LOG] System started
[ALERT] System started
[COUNT] 1

输入分别为 2 和 Warning detected 时的输出示例:

[LOG] Warning detected
[ALERT] Warning detected

输入分别为 1 和 Hello 时的输出示例:

[LOG] Hello

这展示了通过函数指针实现的多态:同一个 fire 调用会根据订阅的处理器触发完全不同的行为。每个处理器都会以自己的方式响应同一个事件,体现了事件驱动设计的松耦合特性。

亲手试试

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

// TODO: 实现 logger 处理函数
// 输出 "[LOG] ",后面接消息
void logger(const char* message) {
    // TODO: 实现
}

// TODO: 实现 alert 处理函数
// 输出 "[ALERT] ",后面接消息
void alert(const char* message) {
    // TODO: 实现
}

// TODO: 实现 counter 处理函数
// 使用静态变量统计调用次数
// 输出 "[COUNT] X",其中 X 是当前计数
void counter(const char* message) {
    // TODO: 使用静态变量实现
}

int main() {
    // 读取要订阅的处理函数数量
    int num_handlers;
    scanf("%d", &num_handlers);
    getchar(); // 读取换行符
    
    // 读取消息
    char message[256];
    fgets(message, sizeof(message), stdin);
    message[strcspn(message, "\n")] = '\0'; // 移除换行符
    
    // TODO: 创建并初始化 Event
    
    // TODO: 根据 num_handlers 订阅处理函数
    // 1 个处理函数:logger
    // 2 个处理函数:logger、alert
    // 3 个处理函数:logger、alert、counter
    
    // TODO: 使用消息触发事件
    
    return 0;
}
quiz icon自我测试

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

面向对象编程中的所有课

自己练习: C 在线编译器