2018q3 Homework2(lab0)
contributed by < type59ty
>
開發環境
預期目標
- 英文閱讀
- C 語言程式設計基礎
- 準備 GNU/Linux 開發工具
- 學習使用 Git 與 GitHub
- 學習效能分析
- 研究自動測試機制
英文閱讀
閱讀以下文件
程式架構
從 github clone lab0-c
先查看裡面有哪些檔案
看一下README.md
需要修改這兩個檔案
- queue.h : Modified version of declarations including new fields you want to introduce
- queue.c : Modified version of queue code to fix deficiencies of original code
在 queue.c 中有這幾個 function:
- q new: Create a new, empty queue.
- q free: Free all storage used by a queue.
- q insert head: Attempt to insert a new element at the head of the queue (LIFO discipline).
- q insert tail: Attempt to insert a new element at the tail of the queue (FIFO discipline).
- q remove head: Attempt to remove the element at the head of the queue.
- q size: Compute the number of elements in the queue.
- q reverse: Reorder the list so that the queue elements are reversed in order.
queue.h
queue.c
q_new()
q_free()
- 功能:清空 queue 的內容
- 作法:先宣告一個 pinter x 指向 head,將x所指到的節點清除,並讓 q 不斷指向下一個節點,直到所有節點都清空,最後清除 q
q_insert_head()
- 功能:從 queue 的前端插入一個節點
- 作法:先分配一個空間給新節點 newh, s 指向這個節點的值,所以使用 strdup() 做一個 s 的副本,然後將 newh 指向原本的 head ,最後修改 q ,讓 q 指向新的 head newh
- 如果 queue 原本是空的,那麼這個節點同時是 head 也是 tail
- strdup:The strdup() function returns a pointer to a new string which is a duplicate of the string s.
strdup 函式可以回傳指向一個 string s 的副本的 pointer,它會根據 s 的大小 locate 一個空間,並且不會影響 s
q_insert_tail()
- 測試 new, insert head, insert tail, free 功能是否正常
- 雖然功能正常,但在 commit 時卻出現錯誤訊息:
- 原因是因為當判定新節點的值為 NULL 後, return false 前應該先把這個空間給清除,否則就產生了 memory leak 的問題,因此作以下修改:
q_remove_head()
- 功能:移除 queue 的 head 節點並回傳它的值
- 作法:跟 free 概念差不多,只是只做第一步並且要考慮如何回傳節點值
這邊使用 strncpy 是因為這個 function 可以設定要 copy 的大小,
題目要求 copy size 為 bufsize-1,並且在字串最後加上 null terminator
q_size()
- 功能:回傳 queue 的 size
- 作法:設定一個變數 size,在作其他操作時都會記錄 queue size的變化,因此可以達到 時間複雜度
q_reverse()
make test
qtest
更新 repository
看了一下其他人的開發紀錄才發現, lab0-c 原始專案有做一點更動,需要 git rebase 更新 fork 出來的專案
學習效能分析
- 後來想了一下發現在 q_insert_head 和 q_insert_tail 中的 strdup function 會使用到 malloc,但使用完卻沒有 free ,因此會造成 memory leak 的問題,這部份還需要做一下調整
研究自動測試機制
Evaluation
Your program will be evaluated using the fifteen traces described above. You will given credit (either 6 or 7 points, depending on the trace) for each one that executes correctly, summing to a maximum score of 100. This will be your score for the assignment—the grading is completely automated.
The driver program driver.py runs qtest on the traces and computes the score. This is the same program that will be used to compute your score with Autolab. You can invoke the driver directly with the command:
linux> ./driver.py
or with the command:
linux> make test
輸入 make test 指令後會執行 driver.py
裡面會執行15個測試,通過測試後即可得到對應的分數
而最後一行,查了一下為什麼他要這樣寫: What does if __name__ == “__main__”
: do?
簡單來說,有些 python 程式需要 import 其他 python 程式當作 module,但沒有妥善處理會連同要 import 的那個程式的其他 function 也一併執行
因此 python 有個機制,當我們要編譯一個 python 程式,e.g example.py 時,編譯器會先定義一個特殊變數: __name__
並賦予它值為 __main__
,所以當我們加上if __name__ == "__main__"
這個判斷,編譯器就會知道現在是在執行原來的程式,
而當其他程式 import example.py時, example.py 的 __name__
會被設為 module 的名稱,而不再是__main__
,因此就不會執行不該執行的區塊