C语言应用笔记:巧妙使用链表分时处理多个任务

C语言应用笔记:巧妙使用链表分时处理多个任务

编码文章call10242025-10-22 21:54:524A+A-

在C语言中,链表是一种常用的数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。利用这些特性,结合函数指针设计多任务系统,可有效缩短多个任务一起执行带来的时间开销。下面是一个简单示例:

具备链表特性的结构体变量定义

typedef struct test_list {
    uint8_t id;             // 用于标识任务编号
    void (*func)(void);     // 用于存放任务地址
    struct test_list *next; // 指向下一个将要执行的节点
} TestList;

定义一个结构体变量,它包含了三个成员:

  • id: 用于标识任务的编号
  • func: 一个函数指针,指向一个无返回值、无参数的函数。这是实现“任务”的关键
  • next: 一个指向相同结构体类型的指针。这是构成链表的基础,它用于指向下一个节点

链表的创建与连接

static void foo1(void) {
    printf("这是函数1\r\n");
    delay(0xFF);
}
static void foo2(void) {
    printf("这是函数2\r\n");
    delay(0xFF);
}
static void foo3(void) {
    printf("这是函数3\r\n");
    delay(0xFF);
}
// 定义任务链表,首尾相连,保证能循环执行
static TestList my_list[] = {
    {.id = 0, .func = foo1, &my_list[1]},
    {.id = 1, .func = foo2, &my_list[2]},
    {.id = 2, .func = foo3, &my_list[0]},
};

在程序编译链接后,这个数组的每个元素的地址就固定了。通过直接在初始化器中使用 &my_list[1] 这样的地址来设置 next 指针,人工地将三个节点连接起来。特别地,最后一个节点指向了第一个节点,从而构成了一个循环链表

链表遍历与任务执行

int main(void) {
    // 创建指针,指向链表头(第一个节点)
    TestList *ptr_list = &my_list[0];
    uint32_t count = 5;

    printf("程序开始运行...\r\n");
    do {
        // 执行当前节点指向的函数
        ptr_list->func();
        // 指针移动到下一个节点
        ptr_list = ptr_list->next;
    } while (count--);
    return 0;
}

这个过程清晰地演示了链表的遍历:通过 next 指针,可以一个接一个地访问链表中的每一个节点,无需使用数组索引。由于是循环链表,当指针移动到最后一个节点后,next 会再次指向第一个节点,可以无限循环下去(本例中由 count 变量控制循环次数)。

输出结果

程序开始运行...
这是函数1
这是函数2
这是函数3
这是函数1
这是函数2
这是函数3
点击这里复制本文地址 以上内容由文彬编程网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

文彬编程网 © All Rights Reserved.  蜀ICP备2024111239号-4