首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C 語言鏈表輸出異常:多出一個隨機值節點的原因與修正

     編輯:程式設計疑難解答

初學 C 語言鏈表時,常遇到「輸出結果最後多出一個莫名其妙的數值」的問題。本文通過具體代碼分析,揭示其根本原因,並給出正確的鏈表構建邏輯。

問題代碼回顧

void append(Node *head) {
    int n;
    Node *p, *news = NULL;
    p = head; // 保存首地址
    while (1) {
        scanf("%d", &n);
        if (n == -1) break;
        p->data = n;           // 先給當前節點賦值
        news = (Node *)malloc(sizeof(Node)); // 再分配新節點
        news->next = NULL;
        p->next = news;        // 當前節點指向新節點
        p = news;              // 移動到新節點
    }
    p = NULL;
}

錯誤分析

當輸入 1 2 -1 時,實際鏈表結構為:

  • 節點 1:data = 1,next → 節點 2
  • 節點 2:data = 2,next → 節點 3
  • 節點 3:未初始化 data,next = NULL

循環結束前,已為「下一個」節點分配了內存並掛鏈,但該節點的 data 從未被賦值,打印時輸出的是棧上隨機殘留值。

正確構建邏輯

void append(Node *head) {
    int n, index = 0;
    Node *p = head, *news = NULL;
    while (1) {
        scanf("%d", &n);
        if (n == -1) break;
        if (index == 0) {          // 首節點直接賦值
            p->data = n;
            index++;
            continue;
        }
        news = (Node *)malloc(sizeof(Node));
        news->data = n;            // 先給新節點賦值
        news->next = NULL;
        p->next = news;            // 再掛鏈
        p = news;
    }
}

核心原則

  1. 先賦值,後分配新節點:只有確定需要新節點時才 malloc,並立即初始化其 data 和 next。
  2. 尾指針法:維護一個指向鏈表最後一個有效節點的指針,每次在尾部插入新節點。
  3. 哨兵節點:引入不存儲數據的頭節點,統一插入邏輯,避免首節點特殊處理。

完整可運行示例

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

typedef struct Node {
    int data;
    struct Node *next;
} Node;

void append(Node *head) {
    int n;
    Node *p = head, *news = NULL;
    while (scanf("%d", &n) == 1 && n != -1) {
        news = (Node *)malloc(sizeof(Node));
        news->data = n;
        news->next = NULL;
        p->next = news;
        p = news;
    }
}

void print(Node *head) {
    Node *p = head->next; // 跳過頭節點
    while (p) {
        printf("%d\t", p->data);
        p = p->next;
    }
    putchar('\n');
}

int main() {
    Node *head = (Node *)malloc(sizeof(Node));
    head->next = NULL;
    append(head);
    print(head);
    return 0;
}

掌握「先構建節點,再接入鏈表」的習慣,即可避免此類越界/臟數據問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved