# 2025q1 Homework2 (quiz1+2)
contributed by < `eleanorLYJ` >
## [2025q1 第 1 週測驗題](https://hackmd.io/@sysprog/linux2025-quiz1)
### 測驗 1
#### 解釋程式碼原理
要完成 list_insert_before,此函式的功能為,將新的 item 插入到 list 中的特定 item 之前。
在完成函式之前,先看 list_item 的結構
```c
typedef struct list_item {
int value;
struct list_item *next;
} list_item_t;
typedef struct {
struct list_item *head;
} list_t;
```
`p` 是指向 list_item_t 指標的指標,因為看到 `*p = item` 故能得知,迴圈跑完, `p` 會移到 `before` 的前一個位置的 `next`,也就是 item 插入的位置。
```c
static list_item_t items[N];
static inline void list_insert_before(list *l, list_item_t *before, list_item_t *item)
{
list_item_t **p;
for (p = AAAA; *p != BBBB; p = CCCC)
;
*p = item;
DDDD = before;
}
```
因此由此推論,迴圈是從 list 的開頭開始跌代,接著每次先對 p 做dereference 得到該指標的下一個地址,然後發現下一個地址等於 `before`,停止迭代。
```c
static inline void list_insert_before(list *l, list_item_t *before, list_item_t *item)
{
list_item_t **p;
for (p = &l->head; *p != before; p = &(*(p)->next))
;
*p = item;
item->next = before;
}
```
### 撰寫合併排序操作
### 測驗 2
### 測驗 3
## [2025q1 第 2 週測驗題](https://hackmd.io/@sysprog/linux2025-quiz2)
### 測驗 1
### 測驗 2
開平方根
### 測驗 3
hash table
從題目敘述得知 hash table 的基礎概念
> hlist_head 只使用一個 first 指標指向 hlist_node,沒有指向串列尾節點的指標。
> hash table 主要是由一個 hlist_head 的動態陣列所構成,每個 entry 指向一個由 struct hlist_node 構成的非環狀 doubly linked list ,hash table 長度依照 bits 給定,可知大小為 2 的冪。
先看需要的雜湊表的結構。
```c
struct hlist_node {
struct hlist_node *next, **pprev;
};
struct hash_key {
int key;
void *data;
struct hlist_node node;
};
```
`find_key()` 是要找值為 key 所在的 `struct hash_key`,若找不到就返回 NULL。
find_key 的實現細節為,先找 key 所在的 hlist,然後迭代 hlist 並逐一比較節點找是否有 key。其中為使用 `container_of` 找在 p 所在的 `struct hash_key` 的位置,比較成員 key 是否等於參數的 key。
```c
static struct hash_key *find_key(map_t *map, int key)
{
struct hlist_head *head = &(map->ht)[hash(key, map->bits)];
for (struct hlist_node *p = head->first; p; p = p->next) {
struct hash_key *kn = container_of(p, struct hash_key, node);
if (kn->key == key)
return kn;
}
return NULL;
}
```
以下補充 container_of 的定義。
```c
/* container_of() - Calculate address of object that contains address ptr
* @ptr: pointer to member variable
* @type: type of the structure containing ptr
* @member: name of the member variable in struct @type
*
* Return: @type pointer of object containing ptr
*/
#define container_of(ptr, type, member)
```
map_add() 函式則負責新增一對 key 與 data 到 hash table 中。如果 key 已經存在,返回,不更新 data。如果不存在,則創建依參數而產生的 hash_key (`kn`),並將其插入到對應的 hlist_head 中。插入操作會確保新的 node 被正確地連接到鏈結串列的頭部,並更新相關的前驅節點指標 pprev。
```c
void map_add(map_t *map, int key, void *data)
{
struct hash_key *kn = find_key(map, key);
if (kn)
return;
kn = malloc(sizeof(struct hash_key));
kn->key = key, kn->data = data;
struct hlist_head *h = &map->ht[hash(key, map->bits)];
struct hlist_node *n = &kn->node, *first = h->first;
n->next = first;
if (first)
first->pprev = &n->next;
h->first = n;
n->pprev = &h->first;
}
```