TAILQ_FOREACH和TAILQ_FIRST的实现代码略。
TAILQ_LAST的作用是计算出队列最后一个元素的地址,它的实现就有点难懂了,用到了TAILQ_ENTRY和TAILQ_HEAD内存布局一样的知识点:
#define TAILQ_LAST(head,headname) \
(*(((struct headname *)((head)->tqh_last))->tqh_last))
队列中的tqh_last字段的值是队列最后一个元素的tqe_next的地址,不是最后一个元素的地址。怎么计算出最后一个元素的地址呢? (structheadname *)(head)->tqh_last获得最后一个元素的tqe_next的地址,并强制转换成队列指针类型,
再对其用->tqh_last 就相当于获得了最后一个元素的tqe_prev地址(因为TAILQ_ENTRY和TAILQ_HEAD内存布局一样),然后解引用就得到了最后一个元素 的地址。很巧妙!