原代碼中 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;
}
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 語言數據結構實現的核心技能。