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

C 語言鏈式隊列實現:結構體指針傳遞與內存管理關鍵點

     編輯:程式設計疑難解答

代碼核心問題

原代碼中 EnQueue 和 DeQueue 函數以值傳遞方式接收 LinkQueue L 結構體,導致對 front、rear 指針的修改無法反映回調用者。

錯誤代碼片段

// 錯誤:值傳遞,修改副本
struct QNode * EnQueue(struct QNode *Q, struct LinkQueue L, char e) {
    L.rear->next = head;  // 修改副本的 rear
    L.rear = head;        // 副本銷毀時丟失
    return Q;
}

正確做法:傳遞指針 / 引用

// C 語言:傳遞指針
void EnQueue(struct LinkQueue *L, char e) {
    struct QNode *head = (struct QNode *)malloc(sizeof(struct QNode));
    if (!head) { printf("error\n"); return; }
    head->data = e;
    head->next = NULL;
    L->rear->next = head;  // 修改原始結構體
    L->rear = head;
}

// C++ 可用引用
void EnQueue(struct LinkQueue &L, char e) { ... }

完整修正實現

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

typedef struct QNode {
    char data;
    struct QNode *next;
} QNode;

typedef struct LinkQueue {
    QNode *front, *rear;
} LinkQueue;

// 初始化:傳遞隊列指針
void InitQueue(LinkQueue *Q) {
    QNode *head = (QNode *)malloc(sizeof(QNode));
    if (!head) { printf("Memory error\n"); exit(1); }
    head->next = NULL;
    Q->front = Q->rear = head;  // 頭節點不存數據
    printf("OK!\n");
}

// 入隊
void EnQueue(LinkQueue *Q, char e) {
    QNode *head = (QNode *)malloc(sizeof(QNode));
    if (!head) { printf("Memory error\n"); return; }
    head->data = e;
    head->next = NULL;
    Q->rear->next = head;
    Q->rear = head;
    printf("ok!\n");
}

// 出隊
void DeQueue(LinkQueue *Q, char *e) {
    if (Q->front == Q->rear) { printf("Queue empty!\n"); return; }
    QNode *p = Q->front->next;
    *e = p->data;
    Q->front->next = p->next;
    if (Q->rear == p) Q->rear = Q->front;  // 最後一個元素出隊
    free(p);
    printf("刪除的隊頭元素為:%c\n", *e);
}

int main() {
    LinkQueue Q;
    InitQueue(&Q);
    
    // 測試入隊
    EnQueue(&Q, 'A');
    EnQueue(&Q, 'B');
    EnQueue(&Q, 'C');
    
    // 測試出隊
    char e;
    DeQueue(&Q, &e);  // 輸出 A
    DeQueue(&Q, &e);  // 輸出 B
    DeQueue(&Q, &e);  // 輸出 C
    DeQueue(&Q, &e);  // 提示空
    
    return 0;
}

關鍵知識點總結

  1. 指針傳遞本質:函數修改指針指向的內容可見,修改指針本身需傳二級指針
  2. 隊列頭節點:引入哨兵節點簡化邊界條件 (空隊列 front==rear 指向頭節點)
  3. 內存管理:malloc 分配,free 釋放,出隊時必須 free 被移除節點
  4. 輸入處理:scanf("%c", &e) 會讀取換行符,需 scanf(" %c", &e) (空格跳過空白)

常見陷阱對比

錯誤寫法後果正確寫法
void f(LinkQueue q)修改副本,調用者無感知void f(LinkQueue *q)
Q->rear = head 無前驅更新斷鏈,舊尾節點 next 不指向新節點Q->rear->next = head; Q->rear = head;
出隊不判空解引用 NULL,崩潰if (Q->front == Q->rear) return;

掌握指針傳遞修改調用者變量是 C 語言數據結構實現的核心技能。

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