• 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语言入门


  • 相关阅读:
    python——列表(数组)
    Base64编码与解码
    1,2,4,5-四嗪-羧基Py-Tetrazine-amine HCl/Py-NH2/NH2CH2CONH-Py2-Tetrazine HCl Salt的性能
    为什么说Java不适合做游戏开发,劣势在哪里?
    【Java】和【C语言】实现一个有序数组的二分查找
    02_SpringMVC从0开始框架搭建
    Hive+Flume+Kafka章节测试六错题总结
    SpringBoot基础入门
    springboot基础(30):Mongodb的下载、安装、启动和连接
    什么是灰度发布?能给技术开发带来什么价值
  • 原文地址:https://blog.csdn.net/m0_54206076/article/details/133932521