bsd-list.h 注释说明

本文介绍了NS2中bsd-list.h文件的链表实现原理及宏定义。通过具体示例Node类,展示了如何使用LIST_HEAD和LIST_ENTRY等宏来创建和操作链表。深入解析了这些宏的具体作用和链表的基本操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

bsdlist.h文件说明             

作者:lzqlgq@gmail.com


我们在NS2中的基类中经常会看到宏LIST_HEAD,LIST_ENTRY等宏,它们实现此类的实体的链表,举一个例子Node类就是一个例子, 在node.h中有如下定义有如下代码

 注意: 代码省略了不相关部分代码
 LIST_HEAD(node_head, Node);

 // 声明链表的头节点结构体 node_head,仅含有Node 型指针 lh_first 一个

        class Node : public ParentNode {

        public:

            static struct node_head nodehead_; // static head of list of nodes

            inline void insert(struct node_head* head) {

                LIST_INSERT_HEAD(head, this, entry);

            }

            inline Node* nextnode() { return entry.le_next; }

        protected:

            LIST_ENTRY(Node) entry;

        // 声明链表指针实体部分,含有两个指针

        }


Node类的实例可以通过结构体变量entry里包含的两个Node*类型的指针来链接成一个链表。


由于NS 软件的特点,我们经常需要读各种组件的代码,以及修改代码,这样对于常用的结构我们必须了解,比如在函数dump中的ifhead_.lh_first,如果我们每次遇到这样的结构都去查找,那么工作量会很大,并且会发现我们总是需要跳转多个文件才可一最终弄通当前的代码含义。


void MobileNode::dump(void)

{

    Phy *n;

    fprintf(stdout, "Index: %d/n", address_);

    fprintf(stdout, "Network Interface List/n");

    for(n = ifhead_.lh_first; n; n = n->nextnode() )

    n->dump();

    fprintf(stdout,/ "--------------------------------------------------/n");

}

所以了解这些宏的含义,和系统已经定义的各种宏就很有必要,下边我们介绍宏的定义以及代码分析。

二、宏定义说明:

ns2里最常用的宏链表定义在文件ns-2.31/lib/bsd-list.h 中,其功能很是大,下边是详细代码分析

//头节点宏

//链表单指针头节点结构体宏

#define LIST_HEAD(name, type)

struct name {

type *lh_first; /* first element */

}



//链表实体用于连接的指针部分、 可在某个类的定义中声明该结构题的实体,就可以用此链表连接此类的实体了

#define LIST_ENTRY(type)

struct {

type *le_next; /* next element */

type **le_prev; /* address of previous next element */

// le_next指向下一个节点,le_prev指向前面节点的 “next element” 的地址,“next elemnet “ lh_first或者 le_next这样用发就同一了接口,实在是高

}

//初始化连表 struct name * head

#define LIST_INIT(head) {

(head)->lh_first = NULL;

}

/* 变量说明:

  • struct name * head,指向链表的头节点

  • listelm, elm为指向一个类/实体的指针

  • field为此elmLIST_ENTRY实体

  • 特别注意 le_prev的处理与众不同,他是二级 指针变量

*/

// 尾插法 elm插入到 listelm后 使用的指针在field

#define LIST_INSERT_AFTER(listelm, elm, field) {

if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)

(listelm)->field.le_next->field.le_prev =

&(elm)->field.le_next;

(listelm)->field.le_next = (elm);

(elm)->field.le_prev = &(listelm)->field.le_next;

}

// 前插法 ,elm插入到listelm

#define LIST_INSERT_BEFORE(listelm, elm, field) {

(elm)->field.le_prev = (listelm)->field.le_prev;

(elm)->field.le_next = (listelm);

*(listelm)->field.le_prev = (elm);

(listelm)->field.le_prev = &(elm)->field.le_next;

}

// 头插法 elm插入到head后边

#define LIST_INSERT_HEAD(head, elm, field) {

if (((elm)->field.le_next = (head)->lh_first) != NULL)

(head)->lh_first->field.le_prev = &(elm)->field.le_next;

(head)->lh_first = (elm);

(elm)->field.le_prev = &(head)->lh_first; //指向指针的指针

}

// 删除elm,由于是双向链表,参数只有两个就可以了

#define LIST_REMOVE(elm, field) {

if ((elm)->field.le_next != NULL)

(elm)->field.le_next->field.le_prev =

(elm)->field.le_prev;

*(elm)->field.le_prev = (elm)->field.le_next;

}

 
(add-to-list 'magic-fallback-mode-alist '(buffer-standard-include-p . c++-mode)) (c-add-style "my-style" '("stroustrup" (indent-tabs-mode . nil) ; use spaces rather than tabs (c-basic-offset . 8) ; indent by four spaces (c-offsets-alist . ( (inline-open . 0) ; custom indentation rules (brace-list-open . 0) (statement-case-open . +) ))) ) (defun my-c++-mode-hook () (c-set-style "my-style") ; use my-style defined above (auto-fill-mode) ;(c-toggle-auto-hungry-state 1) (c-toggle-electric-state 1) ;(c-toggle-auto-newline 1);这个就是遇到了{};之后,自己开新行的 (c-toggle-hungry-state 1) ;(c-toggle-syntactic-indentation 1) ;(define-key c++-mode-map (kbd ":") 'semantic-ia-complete-symbol-menu) ;(define-key c++-mode-map (kbd ".") 'semantic-ia-complete-symbol-menu) (define-key c++-mode-map (kbd "C-c C-c") 'kill-ring-save);copy (define-key c++-mode-map (kbd "C-v") 'yank);paste (define-key c++-mode-map (kbd "C-x x") 'kill-region);cut ;(define-key c++-mode-map (kbd "C-c C-c") 'kill-ring-save);copy ;(define-key c++-mode-map (kbd "C-v") 'yank);paste (setq tab-width 8 indent-tabs-mode nil) ) (add-hook 'c++-mode-hook 'my-c++-mode-hook) (add-hook 'objc-mode-hook 'my-c++-mode-hook) ;--------------------------------传说中的施特劳斯特卢普的C++代码风格 --------------------------------------- ;----------------------------------C风格的对齐----------------------------- (defconst my-c-style '((c-tab-always-indent . t) (c-comment-only-line-offset . 4) (c-hanging-braces-alist . ((substatement-open after) (brace-list-open))) (c-hanging-colons-alist . ((member-init-intro before) (inher-intro) (case-label after) (label after) (access-label after))) (c-cleanup-list . (scope-operator empty-defun-braces defun-close-semi)) (c-offsets-alist . ((arglist-close . c-lineup-arglist) (substatement-open . 0) (case-label . 4) (block-open . 0); (defun-block-intro . 0) (statement-block-intro . 8) (substatement . 8) (knr-argdecl-intro . -))) (c-echo-syntactic-information-p . t) ) "My C Programming Style" ) ;; Customizations for all of c-mode, c++-mode, and objc-mode
最新发布
05-13
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值