--- title: 2020 第一週作業 tags: _核心設計 breaks: true --- # 2020q1 Homework1 (lab0) contributed by < `babysuse` > ## 作業描述 > 首先根據 CMU 的作業描述 - 如圖所示 (pic) - 目標是一個儲存字串的 Singly Linked List - 並且要能區別出兩種特殊狀況 - NULL queue:Queue 為 NULL - empty queue:Queue 的 head field 為 NULL - 然後要實作出以下 functinos 和要求: - `q_new` - `q_free` - `q_insert_head` (LIFO discipline) - `q_insert_tail` (FIFO discipline) - `q_remove_head` - `q_size` - `q_reverse` (rearranging instead of re-allocating) <br> - 用 `malloc` 來配置空間儲存 linked list 中的 strings - 要求 `q_insert_tail` 以及 `q_size` 的複雜度為 $O(1)$ - 測試中將會超過 1,000,000 個 elements - \**其他要求參見 queue.c 和 queue.h 註解* \* - 成功編譯過後會產生 command line 測試程式 *qtest* - 也可以使用 /traces 中的各種測試指令 ```sh $ ./qtest -f traces/trace-eg.cmd ``` - 也有評分程式 ```sh $ ./driver.py ``` 或 ```sh $ make test ``` > 再根據本次作業的追加項目如下 - 修改 sorting 為 natural sort - 運用 Valgrind 排除 qtest 實作的記憶體錯誤 > 加分題 - 擴充 qtest 命令列功能 - 單行或多行編輯 - 歷史命令處理 - 命令自動補完 - 預設開啟 AddressSanitizer 同時滿足效能測試所需 - 指出現有程式的缺陷 ## 實作第一部份:CMU 作業要求(檔案中的 TODO 們) :::warning 程式的複雜度至少包含時間和空間的複雜度,行文應儘量明確聲明 :notes: jserv ::: - 首先是要讓 `q_insert_tail` 以及 `q_size` 的時間複雜度為 $O(1)$ - 就是很直觀的加上 `list_ele_t *tail` 以及 `size_t size` - 再來是處理 malloc 回傳 NULL 的狀況,有關 C 的 Error Handling - 首先 C 會將錯誤類別存入變數 errno (參見[總覽](http://www2.hs-fulda.de/~klingebiel/c-stdlib/sys.errno.h.htm)) - 可以使用 `void perror(const char *str)` 或是 `char *strerror(int errnum)` 取得錯誤訊息(以下等價) - ```perror("an error occurred");``` - ```printf("an error occurred: %s\n", strerror(errno));``` - 由於沒辦法取得其他使用到 heap 的 handler,因此沒辦法去釋放其他被使用的記憶體,所以我直接用 `exit(EXIT_FAILURE)` 退出程式 ??? > - 其餘就是 linked list 的實作,<s>從大一到現在已經做過無數次了,這裡就不再贅述</s>,附上 [github 連結](https://github.com/babysuse/lab0-c/blob/master/queue.c)。唯一不同點在於這次我儘量引入了 Linus 所謂的 taste,以及我在 [Clean Code](https://www.tenlong.com.tw/products/9789862017050) 中所理解到的 clean code。 > :::warning > 做了幾次不是關鍵,而是能否在其中獲得體悟,從細節做起,時時反思工程議題,是課程著重的要求 > :notes: jserv > :::