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

C语言双向链表打印异常:仅最后一个元素输出正确问题排查

错误根因

你的代码存在两处核心问题:

  • add函数遍历找尾节点的循环中,多余执行了before->previous=before;操作,直接把每个遍历到的节点的前驱指针指向了自身,这就是你打印时previous字段和当前节点值一致的直接原因。双向链表尾部加节点的逻辑不需要修改原有节点的前驱指针,这行代码完全多余。
  • main函数的遍历逻辑终止条件设为head->next,会直接跳过最后一个节点(next值为NULL)不会打印,同时直接修改head指针会丢失链表头地址,后续无法再从头部访问整个链表。

修正后的代码

add函数修正版

// 提前定义listw结构体,你本地已有的话可以忽略
typedef struct listw {
    int number;
    struct listw* previous;
    struct listw* next;
} listw;

listw* add(listw* head, int number)
{
    listw* before = head;
    // 仅遍历找尾节点,不要修改原有节点的指针
    if (head)
        while (before->next)
            before = before->next;

    // 不要用new作为变量名,避免和C++关键字冲突
    listw* new_node = calloc(1, sizeof(listw));
    new_node->number = number;
    new_node->next = NULL;
    if (before)
    {
        before->next = new_node;
        new_node->previous = before;
    }
    return head ? head : new_node;
}

打印逻辑修正版

#include <stdio.h>
#include <stdlib.h>

int main(){
    listw* head = add(NULL, 7);  
    head = add(head, 12); 
    head = add(head, 18); 
    head = add(head, 20);

    // 用临时指针遍历,不修改原head指针
    listw* cur = head;
    while (cur != NULL)
    {
        if (cur->previous == NULL)
        {
            // 头节点处理
            if (cur->next)
                printf("previous: none, now: %d, next: %d\n", cur->number, cur->next->number);
            else
                printf("previous: none, now: %d, next: none\n", cur->number);
        }
        else if (cur->next == NULL)
        {
            // 尾节点处理
            printf("previous: %d, now: %d, next: none\n", cur->previous->number, cur->number);
        }
        else
        {
            // 中间节点处理
            printf("previous: %d, now: %d, next: %d\n", cur->previous->number, cur->number, cur->next->number);
        }
        cur = cur->next;
    }

    // 补充内存释放逻辑,避免内存泄漏
    cur = head;
    while (cur != NULL)
    {
        listw* temp = cur;
        cur = cur->next;
        free(temp);
    }
    return 0;
}

额外注意点

  • 动态申请的内存使用完成后必须释放,避免内存泄漏。
  • 遍历链表优先使用临时指针,不要直接修改头指针,避免丢失链表入口。

内容的提问来源于stack exchange,提问作者iwannalearnforreal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 00:36:02