# 2020q3 Homework1 (quiz1)
contributed by <[`hsiehong`](https://github.com/hsiehong/ACSTI)>
###### tags: `進階電腦系統理論與實作`
[作業說明](https://hackmd.io/@sysprog/sysprog2020-quiz1)
----
### `add_entry`
#### `AA1 : assert(new_node);`
#### `AA2 : *indirect = new_node;`
```c=
void add_entry(node_t **head, int new_value)
{
node_t **indirect = head;
node_t *new_node = malloc(sizeof(node_t));
new_node->value = new_value;
new_node->next = NULL;
assert(new_node);//AA1
while (*indirect)
indirect = &(*indirect)->next;
*indirect = new_node;//AA2
}
```
* line 5-7 : 新增一 node
```graphviz
digraph newNode{
node[shape=box,color=red]
rankdir=LR
{
newNode[label=new_node]
NULL[label=NULL,shape=plaintext]
}
newNode->NULL
}
```
* line 9 : `assert(new_node)` 在 [C Library](http://www.cplusplus.com/reference/cassert/assert/?kw=assert)中,此 macro 會比較參數與0。相同的話錯誤訊息會被寫入 standard error device 且會呼叫[abort](http://www.cplusplus.com/reference/cstdlib/abort/)
目的是確保 `new_node` 能分配到空間
* line 12 : line 10 和 line 11,`*indirect` 會從 head 走訪 linked list 的所有節點,在迴圈結束時會停在最後一個節點,此時會將新的節點 `new_node` assign 給`*indirect`,即插入串列尾。
```graphviz
digraph link{
node[shape=box,color=red]
rankdir=LR
{
it[label=indirect, shape=plaintext]
A[]
B[]
C[]
N[label=null, shape=plaintext]
A->B->C->N
nn[label=new_node]
}
{
rank=same
it->N
}
}
```
```graphviz
digraph link2{
node[shape=box,color=red]
rankdir=LR
{
//head[label=head, shape=plaintext]
it2[label=indirect, shape=plaintext]
A[]
B[]
C[]
NN[label=new_node]
Null[label=NULL, shape=plaintext]
A->B->C->NN->Null
}
{
rank=same
it2->NN
}
}
```
----
### `swap_pair`
#### `BB1 : node = &(*node)->next->next`
#### `BB2 : *node = (*node)->next`
```c=
node_t *swap_pair(node_t *head)
{
for (node_t **node = &head; *node && (*node)->next; node = &(*node)->next->next/*BB1*/) {
node_t *tmp = *node;
*node = (*node)->next;//BB2;
tmp->next = (*node)->next;
(*node)->next = tmp;
}
return head;
}
```
* 將 linked list 中的node兩兩一組,並做交換
* line 3 : 走訪 linked list,且一次走訪兩個 node,此處是使用==pointer to pointer==,所以每次要跳兩個 node。
* 一開始沒注意到 **->** 優先權大於 **&**,參考[運算子優先順序](https://magicjackting.pixnet.net/blog/post/70902861)
* line 4-7 : 交換兩個 node 的**指向**
:::warning
dereference 與 reference 概念不清楚, pointer to pointer 概念混亂, 還需要去多找一些資料閱讀
:::
```graphviz
digraph swapGraph{
node[shape=box,color=red]
rankdir=LR
{
head[label=head, shape=plaintext]
A[]
B[]
C[]
D[]
E[]
Null[label=NULL,shape=none]
N[shape=none]
head->A->B->C->D->E->Null
N->A,B
}
}
```
```graphviz
digraph struct{
node[shape=box, color=red]
rankdir=LR
{
head[label=head, shape=plaintext]
A2[label=A]
B2[label=B]
C2[label=C]
D2[label=D]
E2[label=E]
Null2[label=NULL,shape=none]
head->B2->A2->C2 [color=green]
C2->D2->E2->Null2
N2[label="node", shape=none]
}
{
rank=same
N2->C2
}
}
```
```graphviz
digraph swapGraph{
node[shape=box,color=red]
rankdir=LR
{
head[label=head, shape=plaintext]
A[]
B[]
C[]
D[]
E[]
Null[label=NULL,shape=none]
N[shape=none, label="node"]
head->B->A->C
C->D->E[color=green]
E->Null
}
{
rank=same
N->E
}
}
```
----
### `reverse`
#### `CCC : head->next = cursor; cursor = head`
```c=
node_t *reverse(node_t *head)
{
node_t *cursor = NULL;
while (head) {
node_t *next = head->next;
head->next = cursor; //CCC
cursor = head; //CCC
head = next;
}
return cursor;
}
```
* 將整個 linked list 反轉,並回傳反轉後的 head
* `cursor` 在每一個 iteration 中,初始都會在原 linked list 中 `head` 的前一個 node ,`next` 則永遠是 `head` 的下一項,並且將 head->next 指向 cursor (反轉的動作),再將 cursor 指向 head
### 待補
* Graphviz 圖表優化,表達的不夠好,也畫的好醜...
* pointer to pointer 的相關應用