libevent中的尾隊列tailq分析

libevent中的tailq本質上, 就是一個雙向鏈表, 而後記錄下了頭指針和尾指針, 便於順序遍歷和逆序遍歷.spa

因爲C語言中沒有模板, 爲了適應不一樣的數據類型, tailq的操做, 都是使用的宏定義, 致使代碼難以閱讀.指針

爲了方便分析, 本文對tailq相關的結構體進行了簡化:code

struct tailq{
    struct element*  first;
    struct element** last;
};
struct element{
    struct element*  next; //next必須放在第一個位置
    struct element** prev;
    int x;//這裏表示結構體中的其它成員
};

讀者可能有如下一些疑問:element

1. last和prev爲何要使用指針地址, 直接用struct element*不是更簡潔明瞭嗎?event

看下面這段代碼:    ast

struct element** prev;
struct element* elem = malloc(sizeof(struct element));
prev = &elem->next;

根據C語言的規則模板

由於elem == &elem->nextclass

因此: prev == elem效率

即:  next的值elem指針, prev的值也是elem的指針, 只不過形式上是struct element**, 使用時, 能夠直接強轉爲struct elemnt*來操做遍歷

寫了一個普通的雙向鏈表, 與之對比, 得出的結論是, tailq使用指針地址方式, insert_tail的操做少了一條if語句判斷, 效率上更優.

2. 數據存儲的結構是怎樣的, 根據代碼表面上的意義, 能夠畫出這樣一張圖:

綠色表示整個element

藍色表示字段

白色表示值

因爲&next的值, 等於element指針, 因此上圖能夠演變成

這樣, 就很清晰了, prev指向前一個元素, next指向後一個元素, first指向第一人元素, last指向最後一個元素

相關文章
相關標籤/搜索