contributed by < chihen0709 >
Chloexyw
q_insert_head
和 q_insert_tail
中有提到有使用函式 strncpy
,但實際在 GitHub 中並沒有,若能將 GitHub 和共筆的資訊同步更新可以更方便他人進行討論david965154
使用經過 clang-format
風格修正後的程式碼來解釋實作細節的部份。
在 q_merge
你提到了使用 Strategies for Stable Merge Sorting 來實作,在補上實作細節的同時請介紹其方法及如何實作,若與原本實作方法不同,可以說明使用了什麼方法作替代、造成的差異為何。
?
無論標題和內文中,中文和英文字元之間要有空白字元 (對排版和文字搜尋有利)
因為原本的WSL2的環境拿來裝自己跑數值模擬實驗的軟體以及套件,過於複雜所以重新買了SSD安裝了新的作業系統:Ubuntu 22.04.3 LTS
在之前修習計算機結構第一門課程就是在講解數值系統以及 IEEE754
浮點數,從那時對於計算機領域數學一竅不通的我開始接觸這些組成我們所知的電腦背後所組成的數值系統,在那時候透過 CS 61C 的教材以及講解初步認識了一補數和二補數的概念,這次透過老師所撰寫的文章讓我有對計算機編碼的系統有更多的認識,對於傳統工程背景的我來說群論以及數論這些純數學
是對我來說不曾接觸的事物。
解讀計算機編碼
目前簡略了解了在計算機編碼所使用的編碼系統都是群論的延伸及應用,上面這張圖可以透過圓環+溢位的概念和群對稱軸(因為群論最大的目的就是研究對稱性),可以快速的找到編碼後的數值對應的補數,例如:我們如果要找尋 0011
之補數透過群對稱軸可以找到對稱的 1101
這個編碼,此編碼正好恰巧為是 0011
的二補數,也發現一補數對稱軸以及群對稱軸其實偏差了0.5
,透過此可以定義我們在數值系統常用的二補數編碼就是透過群對稱軸找到的對稱的編碼也恰巧剛好是透過 0011
一補數對稱軸所對稱的數值1100
加上0001
的編碼,透過這個概念可以推廣至 8-bits, 16-bits, 32-bits 等系統,關於群論以及數論的基礎概念十分有興趣,待碩士論文撰寫後再來詳細研究才能慢慢了解 linux 核心背後的編碼系統。
不要輕易許下承諾,亦避免輕易相信別人的承諾,不然他人隨後就不當你是一回事 —— 前者輕佻,後者好騙。
謝謝老師指正,學生會注意下次避免再犯 by chihen
本質上都是應用鏈結串列來去撰寫出佇列內的函式來去完成其功能
q_new
這是我第一個開始撰寫的函式,乍看起來十分簡單實作,但對於不熟悉鏈結串列的我,我分成以下步驟來去下手以及思考
1.重新閱讀你所不知道的 C 語言: linked list 和非連續記憶體 中的 Linked list 在 Linux 核心原始程式碼-簡化實作的概念。
2.查看 queue.h
程式碼註解
3.查看 list.h
程式碼註解
4.思考如何產生一個節點
一開始並不知道何從下手,但再次翻閱你所不知道的 C 語言: linked list 和非連續記憶體知道 linux
中 list.h
是一個雙向環狀鏈結串列其核心的使用概念就是 list_head
這個結構體來去每個結構體 下面此圖讓我更好理解其概念。
避免過多的中英文混用,已有明確翻譯詞彙者,例如「鏈結串列」(linked list) 和「佇列」(queue),就使用該中文詞彙,英文則留給變數名稱、人名,或者缺乏通用翻譯詞彙的場景。
且透過 queue.h
關於 q_new
的描述讓我知道是建立一個空佇列且為雙向環狀鏈結串列,所以思考過程會如下:
先定義結構體 struct list_head
後且用 malloc 來去配置記憶體位置給新的 head
然後再使用 INIT_LIST_HEAD
這個函式初始化 queue 成雙向環狀鏈結串列。
為何要做以上操作? 是因為查看 C 語言規格書 ISO/IEC 9899 中的關於 [7.20.3] malloc
, realloc
, calloc
函式的定義:
The pointer returned if the allocation succeeds is suitably aligned so that it may be assigned to a pointer to any type of object
If the space cannot be allocated, a null pointer is returned
所以做以上操作是為了檢查是否有成功配置記憶體,若失敗則提早回傳 NULL
。
q_free
查看 queue.h
逐一走訪鏈結串列並移除節點再釋放記憶體位址,
會使用list_for_each_entry_safe
函式等相關函式。
使用指定的程式碼縮排風格。
在 queue.h
程式碼註解提到若是 no effect if header is NULL
,所以必須先檢查 head
是否為 Null
,然後透過 list_for_each_entry_safe
走訪每個節點,再使用 q_release_element
這個函式 release
所有的 element
,這樣只會剩下開頭定義的 head
再使用 free
函式釋放記憶體位址
q_insert_head
, q_insert_tail
查看 queue.h
描述到記憶體位址配置沒有成功或是為 Null
時為失敗,且 s
必須明確指向執行的字串,所以跟之前一樣先必須查詢是否為 Null pointer
,後面再使用 list_add
函式將新節點加入 list
中。
使用指定的程式碼縮排風格。
透過上述檢查 head
和 s
是不是 Null pointer
,然而在 queue.h
提及 The function must explicitly allocate space and copy the string into it
,查看 liunx man page
可以看到關於 strcpy、strncpy、memcpy
等函式相關的描述可得知 strcpy、strncpy
函式是從 src
複製字串但 strcpy
必須確認其記憶體位址配置是足夠的且必須用 Null byte
結尾 而 strncpy
函式類似 strcpy
函式但只有複製 n
個 bytes
,故此函式我選用 strncpy
函式來完成,而 queue_insert_tail
queue_insert_head
類似只是將 list_add
函式更改為 list_add_tail
這個函式。
改進你的漢語表達,並比對你的說法是否與 C 語言規格書吻合,注意標準函式庫實作的手法。
q_remove_head
, q_remove_tail
目前評分為 95/100,時間複雜度無法通過。
TODO:
不要濫用 :::
,以免造成他人編輯筆記的困難。