int create(list *head) { // 形參是指針副本
head = t; // 修改副本,無法影響主調 main 中的 head
// ...
}
int main() {
list *head = NULL;
create(head); // 傳遞 NULL 值,函數內修改無效
insert(head); // head 仍為 NULL,解引用崩潰
}
list *head 實際是傳遞指針的副本(地址值)。head = t 只是修改副本指向新節點,主調的 head 仍為 NULL。insert(head) 使用未初始化的 NULL 指針,訪問 head->next 觸發段錯誤。list* create() {
list *head = (list*)malloc(sizeof(list));
head->next = NULL;
// 讀取首個數據...
return head; // 直接返回頭結點地址
}
int main() {
list *head = create(); // 接收返回值
insert(head);
// ...
}
list **headvoid create(list **head) {
*head = (list*)malloc(sizeof(list));
(*head)->next = NULL;
// ...
}
int main() {
list *head = NULL;
create(&head); // 傳遞頭指針的地址
insert(head);
}
#include
#include
typedef int ElemType;
typedef struct Node {
ElemType data;
struct Node *next;
} Node, *List;
List create() {
List head = (List)malloc(sizeof(Node));
head->next = NULL;
int x;
printf("Enter numbers (end with 0): ");
while (scanf("%d", &x) == 1 && x != 0) {
List node = (List)malloc(sizeof(Node));
node->data = x;
node->next = NULL;
// 尾插法構建初始鏈表
List p = head;
while (p->next) p = p->next;
p->next = node;
}
return head;
}
void insert_sorted(List head) {
int x;
while (scanf("%d", &x) == 1 && x != 0) {
List node = (List)malloc(sizeof(Node));
node->data = x;
node->next = NULL;
List prev = head, curr = head->next;
while (curr && curr->data < x) {
prev = curr;
curr = curr->next;
}
node->next = curr;
prev->next = node;
}
}
void print_list(List head) {
for (List p = head->next; p; p = p->next)
printf("%d ", p->data);
puts("");
}
int main() {
List head = create();
insert_sorted(head);
print_list(head);
// 釋放內存略
return 0;
}
| 問題 | 原代碼 | 修正 |
|---|---|---|
| 頭指針未回傳 | void create(list *head) | List create() 返回頭指針 |
| 插入排序邊界 | while(1) 無 m->next 判斷先行 | while(curr && curr->data < x) 安全推進 |
| 輸入結束標誌 | 字符 '$' 與 %d 衝突 | 改用整數 0 或 EOF 判斷 |
| 內存洩漏 | 無 free | 主程序退出前遍歷釋放(略) |
「指針傳遞要改變指針本身,必須傳指針的指針,或直接返回新指針」 —— 這是 C 語言鏈表操作的鐵律,牢記於心。