http://blog.csdn.net/u012566181/article/details/38313227
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
struct kool_list
{
struct list_head list;
int to,from;
};
//这个定义把list_head结构放在第一位很有讲究,因为后面
//可以直接利用list_for_each宏来直接得到koo_list的位置,因为
//每个koo_list结构中,如果这样定义的化,那么list的地址和
//结构的地址就是一样的,那时,我们可以直接强制转换即可得到了。
/*int main(int ac,char **av)
{
if(ac!=2)
return 0;
int n=atoi(av[1]);
int i=0;
struct kool_list mylist;
//这定义了一个表头
INIT_LIST_HEAD(&mylist.list);
//初始化表头,注意传递的参数,是list成员的地址 .优先级比&高
struct kool_list *tmp;
struct list_head *pos;
for(i=0;i<n;i++)
{
tmp=(struct kool_list*)malloc(sizeof(struct kool_list));
printf("intput to and from:");
scanf("%d %d",&tmp->to,&tmp->from);
list_add(&tmp->list,&mylist.list);
//像这种对链表的操作,基本伤都是对list的操作,
//所以,传参进去时候要传递成员list的地址。
}
list_for_each(pos,&mylist.list)
{
//这时候,pos是某个struct kool_list结构的list的地址
//所以在通常情况下,需要进行从list找相应的主体结构。
tmp=list_entry(pos,struct kool_list,list);
//这样,tmp现在为pos相应的主体结构struct kool_list的地址了.
printf("%d---%d\n",tmp->to, tmp->from);
//前面说到,因为list是定义的第一个成员,所以,我们也可页这样
//得到主体的结构.
tmp=(struct kool_list*)pos;
printf("%d---%d\n",tmp->to,tmp->from);
}
return 0;
} */
/*在运用list_head的时候,关键是要区分list_head的成员与其主体的关系
不要忘记了。 */
/*很多初学者对于从pos是怎样得到主体的地址的不明白,
//即对与宏list_entry的实现不是很清楚,下面来解释一下.
//毕竟不是每个结构都会把list放在开头的,清楚这个宏
//有一定的好处。
*/
#define list_entry(ptr,type,member)\
((type*)((char*)(ptr)-(unsigned long)(&((type*)0)->member)))
//傻眼了....
//按照上面的例子展开就是
((struct kool_list*)((char*)(pos)-(unsigned long)(&((struct kool_list*)0)->list)));
//下面解释一下
//如果我们要对某个结构中的成员,求出该成员相对于结构首地址的偏移,那么我们应该怎么做
//假如有这样的结构;
struct foo_bar
{
....
int boo;
....
};
//我们要得到boo的偏移,那么这样
(unsigned long )(&((struct foo_bar*)0)->boo);
//是不是简单多了。既然我们得到了boo的偏移,那么计算foo_bar的地址就用bar的地址减去boo的偏移
//即可,(注意,地址是向下增加的)
//
//为了对以上有个感性的认识,那么看个小程序段落.
struct foobar{
unsigned int foo;
char bar;
char boo;
};
int main(int ac,char**av)
{
struct foobar tmp;
printf("address of tmp is=%p\n\n",&tmp);
printf("address of tmp->foo %p \t offset of foo=%lu\n",
&tmp.foo,(unsigned long ) &((struct foobar*)0)->foo);
printf("address of tmp->bar %p \t offset of bar=%lu\n",
&tmp.bar,(unsigned long ) &((struct foobar*)0)->bar);
printf("address of tmp->boo %p \t offset of boo=%lu\n",
&tmp.boo,(unsigned long ) &((struct foobar*)0)->boo);
printf("computed address of &tmp using:\n");
//printf("\t address and offset of tmp->foo=%p\n",
// (struct foobar*)(((char*)&tmp.foo)-((unsigned long )&((struct foobar*)0->foo))));
return 0;
}
list.h 简单运用
最新推荐文章于 2023-09-24 23:13:47 发布