# Linked list-Struct 細節探討與學習(上) ###### tags: `資料結構` Copyright 2021, [月下麒麟](https://hackmd.io/@YMont/note-catalog) --- ## Outline 主要為理解linked list(鏈結串列)的鏈結過程, 因於source code上看到這段,對其for loop運行的結果不理解 ```c= for(ptr=plc_funcs;ptr;ptr=ptr->next) ``` 後來,因找尋到關鍵字為"linked list", 故將學習認知過程紀錄如下。 ## 初步認識 >建立初值 與 指向結構之指標變數, >>程式第11行是重點所在! 指標變數"指向"結構, >>故,該指標就具有該結構的位址,就能進行存取的動作。 ```c= #include <stdio.h> typedef struct s_list slist; struct s_list{ int a ; int b ; }; int main(void) { slist vStruct = {23,5}; //建立slist結構之變數vStruct初始值 slist *vPoint = &vStruct; //建立指向slist結構之指標變數vPoint printf("%d\n",(*vPoint).a);//取值,利用.的方法 printf("%d\n",(*vPoint).b); printf("%d\n",vPoint->a); //取值,利用->的方法 printf("%d\n",vPoint->b); return 0; } /* Output ./main 23 5 23 5 */ ``` --- ## 認識結構位址 >賦予結構記憶體位置 與 輸出結構地址, >>展示取地址、資料; >>程式第12行,利用malloc出一個size為slist大小, >>並將該記憶體位址丟給 指標變數ptr, >>並該ptr指向slist結構 >>如此一來,就能利用ptr去存取slist的成員。 >>~~跟上一段程式稍有不同之處是~~ ```c= #include <stdio.h> #include <stdlib.h> typedef struct s_list slist; struct s_list{ slist *next; int a ; int b ; }; int main(void) { slist *ptr = (slist *)malloc(sizeof(slist)); //配置一個記憶體空間 ptr->a = 47; ptr->b = 49; printf("Address of struct: %p\n",(void*)&ptr); printf("Address of data-a: %p\n",(void*)&ptr->a); printf("Address of data-b: %p\n",(void*)&ptr->b); printf("Address of data-*next: %p\n",(void*)&ptr->next); return 0; } /* Output ./main Address of struct: 0x7ffd4cdde190 Address of data-a: 0x1f12268 Address of data-b: 0x1f1226c Address of *next: 0x1f12260 */ ``` --- ## 單向鏈結串列 (static) Reference:[C語言,鏈結串列 linked list的實作範例](https://lakesd6531.pixnet.net/blog/post/329288496) >應用較簡單的寫法,去實作linked-list鏈結串列 >>可多注意程式第7、11、12、29行,為**將抽象的鏈結化成實作的精隨之美啊!** >>第14~19行,則是表達資料擺放與鏈結行為。 ```c= #include <stdio.h> #include <stdlib.h> typedef struct t_node Node; struct t_node{ int data; Node *next; }; int main(void) { Node p1, p2, p3; Node *ptr = &p1; p1.data = 17; // ptr->data = 12; p1.next = &p2; // ptr->next = &p2; p2.data = 19; p2.next = &p3; p3.data = 21; p3.next = NULL; while(1){ if(!ptr){ break; } else{ printf("address=%p\t" ,ptr); printf("data=%d\t" ,ptr->data); printf("next=%p\t" ,ptr->next); ptr = ptr->next; //個人覺得這行滿重要的! 鏈結下一節點 printf("\n"); } } return 0; } /* Output ./main address=0x7ffe5f132638 data=17 next=0x7ffe5f132628 address=0x7ffe5f132628 data=19 next=0x7ffe5f132618 address=0x7ffe5f132618 data=21 next=(nil) */ ``` **Tips** 判斷指標是否為空(NULL) ```c= while(1){ if(!ptr){ //... } } /*等價於*/ while(ptr!=NULL) ``` --- ## 單向鏈結串列 (dynamic) Reference:[C語言,鏈結串列 linked list的實作範例](https://lakesd6531.pixnet.net/blog/post/329288496) >動態串列更是強大發揮鏈結的彈性 >>關於程式註解有意思的三個地方,建議可多看幾次。 >>以下是筆者對於程式碼理解後,自繪的流程圖。 ```c= #include <stdio.h> #include <stdlib.h> typedef struct t_node Node; struct t_node{ int data; Node *next; }; int main(void) { int i, val, num; Node *first , *current , *previous; printf("Number of nodes: "); scanf("%d",&num); for(i=0; i<num; i++){ current = (Node *)malloc(sizeof(Node)); printf("Data for node %d:",i+1); scanf("%d",&(current->data)); if(i == 0){ first = current; } else{ previous->next = current; //有意思[1] } current->next = NULL; //有意思[2] previous = current; //有意思[3] } current = first; while(current!=NULL){ printf("address=%p\t",current); printf("data=%d\t",current->data); printf("next=%p\t",current->next); current = current->next; printf("\n"); } return 0; } /* address=0x9d8a80 data=17 next=0x9d8aa0 address=0x9d8aa0 data=19 next=0x9d8ac0 address=0x9d8ac0 data=21 next=(nil) */ ``` **圖1** ![](https://i.imgur.com/S3xcZNd.png) --- **圖2** ![](https://i.imgur.com/nm6xX2E.png) --- **圖3** ![](https://i.imgur.com/RuGjTvO.png) --- ## Summary **重點提醒** 1.一般欲讀取結構內容,需用指標變數去操作。 2.建立一個linked-list結構,該結構裡面有一資料(data)、一指向同結構的指標變數(\*next) 因探討篇幅較大,故拆成上下兩篇講解,再請接續學習。 [Linked list-Struct 細節探討與學習(下)](https://hackmd.io/@YMont/rJOnmacmK)