• 2023-10-19 指针与指针的指针,我就不信你脑壳不疼



    点击 <C 语言编程核心突破> 快速C语言入门



    前言

    C实现一个链表,为什么有时候传入指针,有时候传入指针的指针,究竟有什么区别? 今天就简单说说,让你头疼的指针套指针问题。


    一、从一个链表实现说起

    先看一个简单的链表结构:

    我们有一个节点LNode, 包含一个数据data, 一个节点指针next, 将节点指针的类型取名为LinkList, 所以LinkList 本身就是一个指针.

    #include 
    #include 
    
    typedef struct LNode
    {
        int data;
        struct LNode *next;
    } LNode;
    
    typedef LNode *LinkList;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    我们实现一个链表的生成函数CreateList, 它的参数是LinkList的指针, 也就是LNode节点的指针的指针.

    函数会让你输入节点个数,以及每个节点的数值, 形成一个链表,

    int CreateList(LinkList *list)
    {
        LNode *node = NULL;
        int cnt;
        scanf("%d", &cnt);
        for (int i = 0; i < cnt; i++)
        {
            node = (LinkList)malloc(sizeof(LNode));
            if (!node)
            {
                return 1;
            }
            scanf("%d", &node->data);
            node->next = *list;
            *list = node;
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    比如我们输入 3 0 1 2,

    代表链表有3个值, 其值分别是 0, 1, 2.

    而如果从头节点算起, 它的储值顺序是反过来的,

    是 2, 1, 0 这个顺序, 头节点永远得到最后一次输入的值.

    链表
    这就是输入指针的指针的目的,

    我要改变传入参数的那个节点指针的值,

    单单传入节点指针, 将无法做到, 因为C语言没有引用,

    需要通过指针解引用来引用那个需要改变的指针.

    最后是链表的删除, 我还是传入指针的指针,

    链表删除的时候我们是从头节点删除,

    一个一个直至节点指向NULL.

    并且保证, 最后传入函数的 list 指向 NULL.

    如果传入的是LinkList, 则删除链表后list就是一个野指针, 需要格外注意.

    int DeleteList(LinkList *list)
    {
        LinkList temp = NULL;
        while (*list)
        {
            temp = (*list)->next;
            free(*list);
            *list = temp;
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    链表删除

    如果弄懂以上操作, 你可以比较轻松的实现一个栈结构, 后进先出.

    下面是个简单的测试用例, 可以通过断点调试, 一步步看看究竟发生了什么.

    int main()
    {
        LinkList list = NULL;
    
        CreateList(&list);
    
        DeleteList(&list);
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    二、指针, 指针的指针, 头疼的来源

    从上面的例子, 你应该可以基本了解, 在什么时候, 需要操作指针的指针,

    本来一级指针理解起来就不是太容易, 二级指针可以说就比较晦涩了,

    但有的时候, 你不理解二级指针, 可能无法满足一些需求, 同时, 也可能导致野指针的出现,

    对于C这种没有gc垃圾回收机制, 也没有C++这种RAII资源管理机制的语言, 谨慎处理指针和内存, 还是挺费头发的.


    总结

    以上就是在C语言中, 我们运用二级指针作为形参, 实现链表功能的一个简单阐述, 对于C语言, 指针是永远绕不开的话题, 把它玩儿明白, 你就入门了.


    点击 <C 语言编程核心突破> 快速C语言入门


  • 相关阅读:
    2022年“移动云杯”算力网络应用创新大赛圆满落幕,百万大奖揭晓!
    SQL及数据库基础知识点总结
    IT行业的6大热门岗位,薪酬都有多高?
    行为型模式-模板方法模式
    一文看懂:性能监控神器JavaMelody
    小红书《乡村振兴战略下传统村落文化旅游设计》中南大博士许少辉八一新著
    Qt基于Qml超链接使用
    《多功能计算器》 Java程序设计 课程设计
    AI:64-基于深度学习的口罩佩戴检测
    AI推介-大语言模型LLMs论文速览(arXiv方向):2024.05.05-2024.05.10
  • 原文地址:https://blog.csdn.net/m0_54206076/article/details/133932521