typedef struct Node{ int elem; struct node * next; }node,*LinkList;
對於LinkList L: L是指向定義的node結構體的指針,可以用->運算符來訪問結構體成員,即L->elem,而(*L)就是個Node型的結構體了,可以用點運算符訪問該結構體成員,即(*L).elem;
對於LinkList *L:L是指向定義的Node結構體指針的指針,所以(*L)是指向Node結構體的指針,可以用->運算符來訪問結構體成員,即(*L)->elem,當然,(**L)就是Node型結構體了,所以可以用點運算符來訪問結構體成員,即(**L).elem;
在鏈表操作中,我們常常要用鏈表變量作物函數的參數,這時,用LinkList L還是LinkList *L就很值得考慮深究了,一個用不好,函數就會出現邏輯錯誤,其准則是:
如果函數會改變指針L的值,而你希望函數結束調用后保存L的值,那你就要用LinkList *L,這樣,向函數傳遞的就是指針的地址,結束調用后,自然就可以去改變指針的值;
而如果函數只會修改指針所指向的內容,而不會更改指針的值,那么用LinkList L就行了;
下面說個具體實例吧!
#include <stdio.h> #include <stdlib.h> typedef int ElemType; typedef struct Node{ ElemType elem; struct Node * next; }Node, * LinkList;
//初始化鏈表,函數調用完畢后,L會指向一個空的鏈表,即會改變指針的值,所以要用*L
void InitList(LinkList *L) { *L = (LinkList)malloc(sizeof(Node)); (*L)->next = NULL; }
//清空鏈表L,使L重新變為空鏈表,函數調用完后不會改變指針L的值,只會改變指針L所指向的內容(即L->next的值)
void ClearList(LinkList L) { LinkList p; while(p = L->next) free(p); }
//銷毀鏈表L,釋放鏈表L申請的內存,使L的值重新變為NULL,所以會改變L的值,得用*L
1 void DestroyList(LinkList *L) 2 { 3 LinkList p; 4 while(p = (*L)->next ) 5 free(p); 6 free(*L); 7 *L = NULL; 8 } 9 10 void main() 11 { 12 LinkList L = NULL; 13 InitList(&L); 14 ClearList(L); 15 DestroyList(&L); 16 }