C语言结构体基础与双向链表实现指南

苏见山
苏见山
发布时间:2026-10-16 | 5人浏览过
原创

本文详细讲解C语言结构体的定义、别名声明、数组及指针访问方法,并深入剖析如何使用结构体构建静态与动态双向链表。通过包含年月日嵌套结构体及学生数据链表示例,演示pNext与pLast指针的串联逻辑、内存遍历输出及实际应用场景区别。

结构体基本概念

在C语言中,当需要表达一个包含多种不同类型数据的实体时(如学生的姓名、学号、性别、年龄),使用结构体是最佳选择。它允许将不同基本类型或复杂类型的数据组合成一个自定义数据类型。

结构体定义与类型重命名

定义结构体主要有两种常用方式:

  1. 直接使用 struct 关键字:
    struct Student {
        char name[20];
        int id;
    };
  2. 使用 typedef 进行类型重命名:推荐在大中型项目中使用,可显著提高代码可读性。
    typedef struct {
        char name[20];
        int id;
    } Student;
    /* 之后可以直接用 Student s1; 定义变量 */

结构体数组与指针操作

结构体可以像基本类型一样形成数组或使用指针指向。

  • 结构体数组:
    Student stuArray[10]; // 声明包含10个元素的数组
  • 结构体指针:
    Student *pStu = &stuArray[0]; // 指向第一个元素

通过指针访问结构体成员时,应使用 -> 运算符,例如 pStu->id。这不仅比解引用加点语法更简洁,也是处理链表节点的标准写法。

嵌套结构体

当一个结构体的成员本身也是结构体时,称为嵌套结构体。例如,在存储“出生日期”时,可以先定义一个日期结构体,再将其作为学生结构体的成员:

链表原理与双向链表实现

链表是通过指针将多个结构体节点连接起来的线性数据结构。以下示例展示了一个包含4个学生节点的双向链表实现。该结构体不仅包含 pNext(指向下一个节点),还包含 pLast(指向前一个节点)。

核心代码逻辑解析:

#include<stdio.h>

typedef struct date {
    unsigned short Year;
    unsigned char Mon;
    unsigned char Day;
} Date;

struct student {
    char Name[20];
    int number;
    char sex;
    struct student *pNext; /* 指向后继节点 */
    struct student *pLast; /* 指向前驱节点 */
};

int main() {
    int i;
    struct student *pStu;
    // 1. 初始化4个静态节点
    struct student stu1[4] = {
        {"stu1", 1, 'm', 0, 0},
        {"stu2", 2, 'm', 0, 0},
        {"stu3", 3, 'm', 0, 0},
        {"stu4", 4, 'm', 0, 0}
    };

    // 2. 建立双向链接
    stu1[0].pNext = &stu1[1];
    stu1[1].pNext = &stu1[2];
    stu1[2].pNext = &stu1[3];
    
    stu1[3].pLast = &stu1[2];
    stu1[2].pLast = &stu1[1];
    stu1[1].pLast = &stu1[0];
    
    pStu = &stu1[0]; // 设置头指针

    // 3. 正向遍历:从第一个节点到最后一个
    for(i=0; i<4; i++) {
        printf("name=%s, number=%d, sex=%c\r\n", pStu->Name, pStu->number, pStu->sex);
        pStu = pStu->pNext;
    }
    
    // 4. 反向遍历:从最后一个节点回到第一个
    pStu = &stu1[3]; // 重置到头节点
    printf("\r\n");
    for(i=0; i<4; i++) {
        printf("name=%s, number=%d, sex=%c\r\n", pStu->Name, pStu->number, pStu->sex);
        pStu = pStu->pLast;
    }
    
    return 0;
}

静态链表与动态链表的应用区别

链表根据内存分配方式可分为两类:

静态链表

节点数量在程序开始前已知且固定。例如,在嵌入式系统中用于管理LCD多级菜单项,或者单片机串口配置参数等。其优势在于无需频繁申请和释放内存,开销小。

动态链表

节点数量随运行时的条件变化而增减,通常配合 malloc 和 free 使用。适用于不确定数据量的场景,如实时接收串口流数据、操作系统中的任务队列或消息队列。它能有效避免固定大小数组造成的内存浪费或溢出风险。

以上就是C语言结构体基础与双向链表实现的详细内容,更多关于C语言数据结构与指针操作的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表