Preface:
基本上 C 的 Pointer 常常會讓程式員頭痛不已 (debug 到天荒地老, 昏天暗地...), 因此它也成為常見的考題. 底下會以 Linked List 當作背景, 然後使用 Pointer 的 Pointer 進行 Linked List 的 Allocation. 聽起來饒舌, 解釋起來更饒舌... Orz.
Question:
首先假設你有一個 struct 結構如下:
常見的 Linked List 的 Allocation 方法會如下:
上面代碼會建立下面的 Linked List:
接著問題來了, 題目要求你使用 Pointer 的 Pointer (PPL) 改寫 Linked List 的 Allocation.
Possible Sol:
底下是使用 PPL 改寫上面 Linked List 的 Allocation 的其中一個寫法:
接著我們要一行行來解釋上述代碼的運作.
1. 使用 PPL 指向 head 的記憶體位置:
2. Memory allocation for struct LinkedList:
3. 移到 Linked List 當前 node 的下一個位置上 (方便下一個 loop 的 allocation)
4. 繼續 steps 2~3 直到 for loop 結束. (所以下一次為變數 *lastref 分配記憶體位置會指定到 變數 next 上面去!)
Complete Code Ref:
由上面的問題可以看出使用 PPL 的代碼簡潔多, 但是容易寫錯 :p (寫起來漂亮;維護起來痛苦?). 底下為完整代碼, 其中函數 createLL() 是舊有的 Linked List allocation; 而函數 createLL2() 則是使用 Pointer 的 Pointer 改寫的代碼:
執行結果如下:
基本上 C 的 Pointer 常常會讓程式員頭痛不已 (debug 到天荒地老, 昏天暗地...), 因此它也成為常見的考題. 底下會以 Linked List 當作背景, 然後使用 Pointer 的 Pointer 進行 Linked List 的 Allocation. 聽起來饒舌, 解釋起來更饒舌... Orz.
Question:
首先假設你有一個 struct 結構如下:
- struct LinkedList{
- int data;
- struct LinkedList *next;
- };
- typedef struct LinkedList L;
- typedef struct LinkedList *PL;
- typedef struct LinkedList **PPL;
- PL createLL()
- {
- printf("\t[Info] Create LinkedList...\n");
- PL head = NULL, rear = NULL;
- int i;
- for(i=0; i<6; i++)
- {
- PL newNode = malloc(sizeof(L));
- if(newNode==NULL)
- {
- printf("\t[Info] Memory error!\n");
- return NULL;
- }
- newNode->data = i;
- newNode->next = NULL;
- if(rear == NULL)
- {
- head = rear = newNode;
- }
- else
- {
- rear->next = newNode;
- rear = newNode;
- }
- }
- return head;
- }
接著問題來了, 題目要求你使用 Pointer 的 Pointer (PPL) 改寫 Linked List 的 Allocation.
Possible Sol:
底下是使用 PPL 改寫上面 Linked List 的 Allocation 的其中一個寫法:
- PL createLL2()
- {
- PL head = NULL;
- printf("\t[Info] Create LinkedList...\n");
- PPL lastref = &head;
- int i;
- for(i=0; i<6; i++)
- {
- *lastref = malloc(sizeof(L));
- (*lastref)->data = i;
- (*lastref)->next = NULL;
- lastref = &((*lastref)->next);
- }
- return head;
- }
1. 使用 PPL 指向 head 的記憶體位置:
2. Memory allocation for struct LinkedList:
3. 移到 Linked List 當前 node 的下一個位置上 (方便下一個 loop 的 allocation)
4. 繼續 steps 2~3 直到 for loop 結束. (所以下一次為變數 *lastref 分配記憶體位置會指定到 變數 next 上面去!)
Complete Code Ref:
由上面的問題可以看出使用 PPL 的代碼簡潔多, 但是容易寫錯 :p (寫起來漂亮;維護起來痛苦?). 底下為完整代碼, 其中函數 createLL() 是舊有的 Linked List allocation; 而函數 createLL2() 則是使用 Pointer 的 Pointer 改寫的代碼:
- #include
- #include
- struct LinkedList{
- int data;
- struct LinkedList *next;
- };
- typedef struct LinkedList L;
- typedef struct LinkedList *PL;
- typedef struct LinkedList **PPL;
- PL createLL()
- {
- printf("\t[Info] Create LinkedList...\n");
- PL head = NULL, rear = NULL;
- int i;
- for(i=0; i<6; i++)
- {
- PL temp = malloc(sizeof(L));
- if(temp==NULL)
- {
- printf("\t[Info] Memory error!\n");
- return NULL;
- }
- temp->data = i;
- temp->next = NULL;
- if(rear == NULL)
- {
- head = rear = temp;
- }
- else
- {
- rear->next = temp;
- rear = temp;
- }
- }
- return head;
- }
- PL createLL2()
- {
- PL head = NULL;
- printf("\t[Info] Create LinkedList...\n");
- PPL lastref = &head;
- int i;
- for(i=0; i<6; i++)
- {
- *lastref = malloc(sizeof(L));
- (*lastref)->data = i;
- (*lastref)->next = NULL;
- lastref = &((*lastref)->next);
- }
- //printf("\t[Test] head->data=%d\n", head->data);
- return head;
- }
- void showLinkedList(PL head)
- {
- printf("\t[Info] Show LinkedList...\n");
- PL temp = head;
- while(temp!=NULL)
- {
- printf("%d ", temp->data);
- temp = temp->next;
- }
- printf("\n");
- }
- void delLinkedList(PL head)
- {
- printf("\t[Info] Free LinkedList...\n");
- PL temp=head;
- while(temp!=NULL)
- {
- temp = head->next;
- free(head);
- head = temp;
- }
- }
- int main()
- {
- PL head=NULL;
- head = createLL2();
- if(head == NULL)
- {
- printf("\t[Error] Fail!\n");
- return 0;
- }
- showLinkedList(head);
- delLinkedList(head);
- return 0;
- }
沒有留言:
張貼留言