原代碼 `void init(List w)` 形參為值傳遞,函式內 `w = malloc(...)` 只修改副本,呼叫端 `list1` 仍為野指標。
typedef struct Node { int data; struct Node* next; } *List;
void init(List w) { w = malloc(sizeof(struct Node)); w->next = NULL; } // 錯誤
int main() { List L; init(L); } // L 未改變
void init(List* w) { // 形參:指標的指標
*w = malloc(sizeof(struct Node));
(*w)->next = NULL;
}
int main() {
List L; init(&L); // 傳遞 L 的位址
}
void init(List& w) { w = malloc(sizeof(struct Node)); w->next = NULL; }
int main() { List L; init(L); }
List init() {
List head = malloc(sizeof(struct Node));
head->next = NULL;
return head;
}
int main() { List L = init(); }
#include
#include
typedef struct Node { int data; struct Node* next; } Node;
typedef Node* List;
List createList() {
List head = malloc(sizeof(Node));
head->next = NULL;
return head;
}
void insertTail(List head, int val) {
Node* p = head;
while (p->next) p = p->next;
Node* n = malloc(sizeof(Node)); n->data = val; n->next = NULL;
p->next = n;
}
void printList(List head) {
for (Node* p = head->next; p; p = p->next) printf("%d ", p->data);
puts("");
}
void freeList(List head) {
Node* p = head;
while (p) { Node* n = p->next; free(p); p = n; }
}
int main() {
List L = createList();
for (int i=1; i<=5; ++i) insertTail(L, i*10);
printList(L); // 10 20 30 40 50
freeList(L);
return 0;
}
「C 語言函式要修改呼叫端指標變數本身,**必須傳遞指標的位址 (二級指標) 或回傳新指標**」,單級指標值傳遞只能修改指向的記憶體內容,無法修改指標變數本身。
掌握此原則,鏈表初始化、插入、刪除、反轉等所有修改頭指標的操作都能寫對。