【基础】单链表基础及实列分析-C

这里主要是记录一些我学习C语言中的一些知识点或个人思考过程

1.程序设计要求

  假设要编写一个程序,让用户输入一年内看过的所有电影(包括DVD和蓝光光碟)。要储存每部影片的各种信息,如片名、发行年份、导演、主演、片长、影片的种类(喜剧、科幻、爱情等)、评级等。建议使用一个结构储存每部电影,一个数组储存一年内看过的电影。为简单起见,我们规定结构中只有两个成员:片名和评级(0~10):理想的情况是用户可以不确定的添加数据(或者不断的添加数据直到使用完内存),不用事先指定输入多少项,也不用程序分配多余的空间.

1.1 链表的简要介绍:

  如下图所示,一个基本的单链表就是这样,其原理也是这样:每次使用 malloc()为新结构分配空间时,也为新指针分配空间。但是,还得需要另一个指针来跟踪新分配的指针,用于跟踪新指针的指针本身,也需要一个指针来跟踪,以此类推。
在这里插入图片描述
具体可结合代码进行详细分析:

2 代码实现及详细注释

2.1 代码及其注释

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 首先要有一定的C基础
#define TSIZE 45

struct MOVE
{
    char name[TSIZE + 1];
    int rating;
    struct MOVE *NEXT;
};

int main()
{
    struct MOVE *head = NULL;
    char input[TSIZE + 1];
    struct MOVE *prev, *current;
    char ch;

    puts("Please input moves that you have saw");
    puts("IF no,please enter ENTER");
    while (gets(input) != NULL && input[0] != '\0')
    {
        current = (struct MOVE *)malloc(sizeof(struct MOVE)); // 申请空间
        if (head == NULL)
        {
            head = current; // 第一次输入时要把人口记录下来
        }
        else
        {
            prev->NEXT = current; // 运行到这行代码时说明已经至少循环过一轮,那么这时候.
                                  // prev存储的是上一次更新结构体指针.
                                  // 所以要是上一次的结构体指针中的next要指向这次更新的结构体指针current.
        }
        current->NEXT = NULL; // 不确定这次是不是最后一次循环,所以先把这次(也可能是最后一个)更新的current中的next指向空指针
        strcpy(current->name, input);
        puts("Please input rating");
        scanf("%d", &current->rating);
        prev = current; // 存储这次更新的current,方便下次循环时使用,至少在这条语句之前,prev一直存储的是上一次更新的current
        puts("Please input next moves that you have saw");
        puts("IF no,please enter ENTER");
        while ((ch = getchar()) != '\n' && ch != EOF) // 清除缓存区的值,以免输入换行符造成不必要的干扰
            ;
    }
    current = head;
    // 看到这行代码有没有疑问?如果直接赋值会不会让最后current中的内容被换掉
    // 如果有疑问,其实是结构体指针和结构体搞混了,current结构体指针的值改变了,但是其原来指向的内容并没有发生变化
    // 原来的current结构体指针指向的结构体,其结构体地址已经被上一个结构体中结构体指针next存储了,
    // 所以循环结束后的current实际上已经没用了
    while (current != NULL)
    {
        printf("%s\r\n", current->name);
        printf("%d\r\n\r\n", current->rating);
        current = current->NEXT;
    }

    /*完成任务释放申请的内存*/
    current = head;
    while (current != NULL)
    {
        current = head; // 思考一下清理的过程,是比较简单的
        head = head->NEXT;
        free(current);
    }

    // getchar();
    return 0;
}

2.2 代码关键分析

  个人理解,对于一个这样的单链表,一般三个量是必须的,头指针head,中间记忆量指针prev,以及每次进行更新的指针量current;其过程如下图,红色的双引号是只虚拟的标志:请添加图片描述
  程序中理解的关键是中间指针prev每次都把上一次创建的结构体指针给存储下来,就如同下面的小例子,比如kj的值,每次循环中j都把k的上一次值给存储且打印出来:
小例子:
在这里插入图片描述

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值