You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言链表添加元素后根节点指针未更新问题求助

问题根源:C语言的值传递机制

你遇到的问题本质是对C语言函数参数传递方式的误解——C里所有参数都是值传递,也就是说当你把raiz_idoso传给adicionar函数时,函数拿到的只是这个指针的副本。你在函数内部给这个副本分配内存、修改它的指向,完全不会影响main函数里原来的raiz_idoso变量,它依然是NULL。这就是为什么函数内部printf能看到值,但main里访问会出问题的原因。

解决方案1:传递指针的指针(推荐用于链表操作)

要让函数能修改原指针的指向,你需要传递指针的指针(也就是struct nodo **类型),这样函数就能通过这个二级指针访问并修改原指针的值。

修改后的adicionar函数应该是这样:

void adicionar (struct nodo ** raiz, int id, int idade){
    if (*raiz == NULL){
        printf("oi");
        *raiz = (struct nodo *)malloc(sizeof(struct nodo));
        (*raiz)->id = id;
        (*raiz)->idade = idade;
        (*raiz)->prox = NULL;
    } else if ((*raiz)->prox == NULL){
        struct nodo * temp;
        (*raiz)->prox = (struct nodo *)malloc(sizeof(struct nodo));
        temp = (*raiz)->prox;
        temp->id = id;
        temp->idade = idade;
        temp->prox = NULL;
    } else{
        adicionar(&((*raiz)->prox), id, idade);
    }
}

然后在main函数里调用的时候,要传指针的地址:

adicionar(&raiz_idoso, id, idade);
// 同理,非老年链表的调用也要改:
adicionar(&raiz_nidoso, id, idade);

解决方案2:让函数返回修改后的指针

另一种方式是让adicionar函数返回修改后的头指针,这样main函数可以用返回值更新原变量:

struct nodo * adicionar (struct nodo * raiz, int id, int idade){
    if (raiz == NULL){
        printf("oi");
        raiz = (struct nodo *)malloc(sizeof(struct nodo));
        raiz->id = id;
        raiz->idade = idade;
        raiz->prox = NULL;
    } else if (raiz->prox == NULL){
        struct nodo * temp;
        raiz->prox = (struct nodo *)malloc(sizeof(struct nodo));
        temp = raiz->prox;
        temp->id = id;
        temp->idade = idade;
        temp->prox = NULL;
    } else{
        raiz->prox = adicionar(raiz->prox, id, idade);
    }
    return raiz;
}

调用的时候要更新原变量:

raiz_idoso = adicionar(raiz_idoso, id, idade);
raiz_nidoso = adicionar(raiz_nidoso, id, idade);

额外需要修复的问题:remover函数

你的remover函数也存在完全相同的问题——它修改的是形参raiz的副本,根本没改变原链表的头指针。同样需要用上面两种方法之一修复,比如用指针的指针(同时别忘了解决内存泄漏问题):

void remover (struct nodo ** raiz){
    if (*raiz != NULL){
        struct nodo * temp = *raiz; // 保存原头节点,避免内存泄漏
        *raiz = (*raiz)->prox;
        free(temp); // 释放不再使用的堆内存
    }
}

调用时也要传地址:

remover(&raiz_nidoso);
remover(&raiz_idoso);

内容的提问来源于stack exchange,提问作者JOAO VITOR PEREIRA VENTURA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 13:17:39