contributed by < Shengyuu
>
q_new
: 新增一空的 queueq_free
: 清除 queueq_insert_head
: 在 queue 的頭插入一元素(LIFO)q_insert_tail
: 在 queue 的尾插入一元素(FIFO)q_remove_head
: 移除 queue 的開頭元素並輸出q_size
: 回傳 queue 有多少個元素q_reverse
: 反轉 queue 中元素的順序q_insert_tail
& q_size
的複雜度要是 queue.h
q_insert_tail
& q_size
的複雜度為 ,在 struct 裡面新增 head, size 兩元素queue_new()
注意程式碼縮排風格是 4 個空白字元和 K&R,連同共筆列出的程式碼也需要變更
q_free()
q_insert_head()
注意:程式碼的排版有明確要求,在 HackMD 和 GitHub 都嚴格遵守,請留意。需要變更本共筆所有程式列表 (可自 GitHub 的分支上複製)
已更改
Shengyuu
一開始將三種需要 return false 的可能寫在同一個 if case 裡面統一判斷,但 qtest 一直出現 error 訊息,後來才想到若第一次 malloc 給 newh 記憶體 失敗的話,第二次 malloc 給 newh->value 記憶體就會是個有問題的寫法
q_insert_tail()
◎第一次完成這個 function 時只記得做 q->tail->next = newt ,而忘了 q->tail = newt ,造成tail都沒有被更新到
q_remove_head()
◎ 在做 free(q->head->value) 的時候若 value 的值為 NULL 應該未出問題––待修改
q_size()
q_reverse()
◎ 剛開始完成這段程式碼的時候是將 q->head = q->head->next 寫在下面一行 tmp_ele… 的後面,編譯後 qtest 顯示 error ,回去檢查程式碼才發現 q->head… 一定要寫在前面,因為此時的 tmp_ele 和 q->head 是除存同一個記憶體位置的,若先將 tmp_ele->next 改掉,就沒辦法找到我們要的下一筆資料了
避免用「噴出」這種語意不明的詞彙,改為「qtest 顯示…」
已更改
Shengyuu
在終端機上輸入 $make test
即可使用自動評分系統,第一步先去 Makefile 內看 test
做了什麼事
從這裡可以看出來當我們在下指令 make test
的時候其實是去執行 scripts/driver.py
,下一步去看 driver.py
做了些什麼
在 driver.py
中主要執行 test 的部份都被包在 class Tracer 內, run
函式只負責處理參數、創建 class Tracer 和呼叫 Tracer 內的 run
函式 ,下面程式碼是 run
函式創建 class Tracer 程式碼
Tracer 最前面將測試檔案的路徑以及每小題的分數都存在陣列型態的變數中,如下:
Trce 的邏輯則是透過物件內的 run
函式以 for 迴圈的方式將每筆資料都送進 runTrace
函式進行 Trace 的動作,如下:
runTrace
函式內透過 clist
變數儲存執行 qtest 的命令,並透過 subprocess 的技巧創建一個子進程執行 qtest,程式碼如下:
clist 儲存的命令如下:
qtest 才是整個自動評分系統的主體,系統將測試時會用到的 function 都當成一個一個 cmd ,並且給予每個 cmd 獨有的 name 和 documents ,將這些資料都存在 struct cmd_ptr
中並用 linked list 結構將所有 cmd 串接起來,struct cmd_ptr
如下:
利用 add_cmd
函式將 cmd 串接在全域變數 cmd_list
, qtest.c
提供一些對 queue 進行操作的 cmd 如下:
console.c
也提供了一些和 queue 無關的操作,如下:
qtest 的 main
函式將基本的參數初始化後會呼叫 run_console
函式, run_console
函式用 while 迴圈包住 cmd_select
函式,直到使用者 quit 才會離開,run_console
函式如下:
cmd_select
會呼叫 read_line
函式將指令 parse 出來,並透過 interpret_cmd
函式在 cmd_list 中搜尋對應指令且執行,下面為搜尋指令過程的程式碼:
進階電腦系統理論與實作 (Fall 2019)
Linux 核心設計 2019