链表的指针疑惑http://bbs.csdn.net/topics/390335607引用这个帖子,我也有同样的疑问。经常在linux代码中看
链表的指针疑惑 http://bbs.csdn.net/topics/390335607 引用这个帖子,我也有同样的疑问。 经常在linux代码中看到如下封装的结构体:
typedef struct head { struct head *next; struct head *front; }head; typedef struct file { head h; int name; int format; }file;还有下面的一种方法:
typedef struct file { int name; int format; file *next; file *front; }file; 我想问的是上面的那种封装方法相对于下面这种封装方法有什么明显的优势吗?我反倒觉得后面的那种写法要更简洁一点。
c 指针 链表 结构体
[解决办法] 第二种表达中的front和next指针都包含了name和format两个变量,这会导致链表中每个指针都含有name和format,显然不是期望的。
[解决办法] 看看<<Understanding the Linux Kernel 3rd Edition>>这本书的3.2.2.3. Doubly linked lists
主要是为了通用,或者抽象.在linux内核中有很多抽象的东东,如slab等.
[解决办法] 上面的写法非常高明,它把数据和结构分离开来:
head h; 是结构部分
int name; 是数据部分
int format; 是数据部分
引用: http://bbs.csdn.net/topics/390335607 引用这个帖子,我也有同样的疑问。 经常在linux代码中看到如下封装的结构体: C/C++ code?123456789101112typedef struct head{ struct head *next; struct head *front;}head; typedef…… [解决办法] 第一种适合,工程类的程序,数据类型复杂,数据量多,条理清晰;第二种适合自己写小型算法题目,简单方便
[解决办法] 第一种寫起來麻煩點,但是更清晰,給head一個好點的名字,比如link,node應該都比head來的好理解。
第二种用該是這樣吧。
typedef struct file
{
int name;
int format;
struct file *next;
struct file *front;
}file;
[解决办法] 同意5楼,linux自己提供的一个双向链表也是这样做的,例如你这次定义一个数据类型为int的链表,下一次建立一个short类型的链表,岂不是要重复写struct file *next; struct file *front;
[解决办法] 这样实际上已经是用C语言模拟面向对象的写法了:
1、head相当于链表的基类;
2、file相当于链表的一个派生类,它继承了链表的基本结构,发展了自己的属性数据。
如果楼主看过Python源代码剖析就会更加清楚这样的设计。
引用: 引用:上面的写法非常高明,它把数据和结构分离开来: head h; 是结构部分 int name; 是数据部分 int format; 是数据部分 引用:http://bbs.csdn.net/topics/390335607 引用这个帖子,我也有同样的疑问。 经常…… [解决办法] 对很多初学来说,普遍都更喜欢接受第二种写法,
毕竟第二种写法要简单很多啊,
如果第一种写法需要:p->h->next;第二种写法只需要:p->next,
如果懂一点代码优化的人,还会说第二种写法少进行一次寻址,效率
还比第一种高呢。那为什么会产生第一种写法呢?
为了解释为什么会有第一种写法,我们假设我们现在需要开发一个
资产管理系统,为了后面讨论简单,我们假设我们需要管理一个开发部门
里面的如下四个资产:
电脑(显示器,键盘,鼠标,主机,网线,电源线)
办公桌 凳子 饮水机 现在抛开别的子系统,单纯来看如果在程序中表示资产呢,要描述每一个资产的 买入时间,使用时间,...一系列详细情况。 首先,肯定不能用一个结构体封装以上所有资产,建设每个资产就是一个结构体类型 那么就有4个结构体类型了(用面向对象的说法就是4个类)。 比如说管理电脑,肯定不能用数组,那么就用链表好了(为了讨论方便,这里不使用别的结构) 也就是说4中资产,都表示成链表。 如果用第二种表示链表的方法写代码,那么每一种资产都需要单独处理next和front这两个成员, 相当于在你的代码中,需要自己写4遍有关链表的操作。那么维护代码就会变得很困难,毕竟链表 操作相关的代码就需要写4遍,哪一遍写错了还不能确定,万一现在需要添加一个电灯,那么又要 再写一遍链表相关的操作,这肯定是不太好的,那么有没有一种方法,能让我写的代码能重用呢? 如果把链表的next和front提出来,放在一个单独的结构中,然后针对这个结构, 编写一套链表相关的操作 int insert(head *h); int del_node(head *node); int is_empty(head *h); int get_next(head *h); ... 再在资产中嵌入这个结构,那么链表相关的代码只用编写一遍,并且易于维护和调试。 因此会有第一种写法。 这个相当于是用C语言实现了继承[解决办法]
引用: 引用:上面的写法非常高明,它把数据和结构分离开来: head h; 是结构部分 int name; 是数据部分 int format; 是数据部分 引用:http://bbs.csdn.net/topics/390335607 引用这个帖子,我也有同样的疑问。 经常…… 我没看过内核代码,不知到他是怎么用的,但是我以前见过一种struct的用法,可以实现,就是将struct的第一个元素地址强转为struct的地址。这样可以引用的struct中的其他成员。比如:
struct file *f = (struct file *)(head->front);
这样就能够得到前一个节点的数据了。