# 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**

---
**圖2**

---
**圖3**

---
## Summary
**重點提醒**
1.一般欲讀取結構內容,需用指標變數去操作。
2.建立一個linked-list結構,該結構裡面有一資料(data)、一指向同結構的指標變數(\*next)
因探討篇幅較大,故拆成上下兩篇講解,再請接續學習。
[Linked list-Struct 細節探討與學習(下)](https://hackmd.io/@YMont/rJOnmacmK)