数组和链表safe

编程入门 行业动态 更新时间:2024-10-08 01:32:46

<a href=https://www.elefans.com/category/jswz/34/1771288.html style=数组和链表safe"/>

数组和链表safe

 数组

数组是需要使用连续内存时候申请的一种内存,int a[10],声明定义必须制定大小

int a[]可作为参数传入是代表a的首地址

访问数组内的数据:a[1]下表方式,其实也是一个地址取值,去a+1的地址上取值*(a+1)

一个数据+1代表,地址后移数据的类型大小sizeof(a)

连续内存申请:

 结构体中的最后一个元素为int buf[0],这时候buf是不占内存大小的

当malloc申请大于结构体本身内存大小时候,buf就可以指向了后台多余内存的地址和类型

链表

链表用于不定长的不连续内存的申请

不定长:每加一个元素都是看时机的,所以每次都要malloc

不连续,每次malloc的时候只是一个元素,和前面元素不连续,就需要一根线连起来,不然我们就把前面的元素弄丢了

struct list {

    struct list *prev,*next;

};

链表仅是一根线,线上有自己的数据类型mydata

struct mylist {

    void *mydata;

    struct list;

};

还需要解决的问题:添加一个,删除一个,遍历查找数据

struct inline void __list_add(struct list  *new, struct list  *prev, struct list  *next)
{
    next->prev = new;
    new->next = next;
    new->prev = prev;
    prev->next = new;
}

添加需要知道新的数据地址,要添加的地方,

需要建立关系:前一数据的后,后一数据的前,新数据的前,新数据的后

struct inline void list_add(struct list  *new, struct list  *head)
{
    __list_add(new, head, head->next);
}

添加尾部,确定位置是链表头的前一元素

struct inline void list_add_tail(struct list  *new, struct list  *head)
{
    __list_add(new, head->prev, head);
}

删除一个元素,需要确定关系删除数据的前面数据的后,删除数据的后面数据的前

struct inline void __list_del(struct list  *prev, struct list *next)
{
    prev->next = next;
    next->prev = prev;
}

要删除的元素需要链表赋值清零

struct inline void list_del(struct list  *entry)
{
    __list_del(entry->prev, entry->next);
    entry->next = (void *) 0;
    entry->prev = (void *) 0;
}

 

遍历,从头开始遍历,到循环到头停止

开始赋值,pos=head->next,这里head没有mydata

条件:pos!=head

执行动作:pos=pos->next

safe:删除当前节点时候,执行动作会有空指针,所以需要n预先存储pos->next

 

//CPU提供的 prefetch 指令将数据放入缓存
#define list_for_each(pos,head) \
for (pos = head->next, prefetch(pos->next); pos != head;\
    pos = pos->next, prefetch(pos->next))

#define list_for_each_prev(pos,head) \
for (pos = head->prev; pos != head; pos = pos->prev)
//因此只遍历链表不删除节点时可以使用前者,若有删除节点的操作,则要使用后者


#define list_for_each_safe(pos, n, head) \
for (pos = head->next, n = pos->next; pos != head; pos = n, n = pos->next)

知道结构体内某一成员变量地址,求结构体地址
//上到下加法,下到上减法
#define list_entry(ptr, type, member) \
((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))

type 0地址是结构体所在地址,那么member就是绝对地址,member的相对地址ptr就可以求得结构体当前地址

#define container_of(ptr, type, member) ({          \
    const typeof(((type *)0)->member)*__mptr = (ptr);    \
             (type *)((char *)__mptr - offsetof(type, member)); })

更多推荐

数组和链表safe

本文发布于:2024-02-28 01:13:35,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1767569.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:数组   链表   safe

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!