1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > C语言 泛型链表 如何计算(结构体中各元素)相对内存地址?(字节对齐 结构体对齐

C语言 泛型链表 如何计算(结构体中各元素)相对内存地址?(字节对齐 结构体对齐

时间:2022-04-26 17:02:22

相关推荐

C语言 泛型链表 如何计算(结构体中各元素)相对内存地址?(字节对齐 结构体对齐

示例:

typedef struct _user {char name[20];char sex[20];int age;struct list_head mylist;//自定义结构体里保存双向循环链表头结点}user;

如果知道mylist的地址,如何获取user的地址呢?

可以这样:

u = (user*)((int)pos1 - sizeof(user) + sizeof((((user*)0)->mylist)));

使用mylist的地址pos1,减去user与mylist的容量大小之差,再将结果转换回user*类型,最后得到的就是user u的地址

注意:对指针直接加减,是相对于这个指针它自身的类型的,要把指针地址转换成实际数值再相加减

(user*)0用法可参考:C语言如何获取结构体中指定元素的大小?sizeof ( (X*)0 ) -> Y)

ffffff

但是不得不考虑到可能存在对齐的情况,就是空间与实际存储的数据大小不一致的情况,可见:C语言 如何计算结构体的大小

比如这里就发生了地址对齐:

char sex之后age之前空出了两个字节的存储空间,以满足后面int类型大小的倍数,但是因为在mylist之后就没发生过字节对齐的情况,(mylist存放的是prev* 和next*两个指针),所以对结果不影响

但是如果mylist之后还存在特殊情况,用上面的方法还能计算出mylist和user真实的地址差吗??

我们再来做个小测试:

&((user*)0)->mylist;&(((user*)0)->mylist);(int)&((user*)0)->mylist;

这个语法,实际上就是offsetof函数,但是我用不了这个函数不知道咋回事,直接把它源码弄来!

可以看到,->是比&优先级高的,所以不用加括号()

offsetof()函数是啥,可以看这:C语言中 offsetof 的使用

这个函数可以求得结构体中元素(头)相对于结构体(头)的地址差!

所以我们想要通过元素(头)地址求结构体(头)地址,只要这样即可:

u = (user*)((int)pos1 - (int)&((user*)0)->mylist);

是不是又比我们开头那会用的又简单了很多???!!!

参考文章:C语言如何获取结构体中指定元素的大小?sizeof ( (X*)0 ) -> Y)

完整泛型链表代码:by jianggong

main.c不是main.cpp!!

#include <stdio.h>struct list_head {struct list_head* next;struct list_head* prev;};#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)//根据structd的成员获取struct的地址#define container_of(ptr, type, member) ((type *)(((char *)ptr) - (int)(&(((type*)0)->member))))//链表遍历#define list_for_each(pos, head) \for (pos = (head)->next; pos != (head); pos = pos->next)#define list_for_each_prev(pos, head) \for (pos = (head)->prev; pos != (head); pos = pos->prev)#define LIST_HEAD_INIT(name) { &(name), &(name) }#define LIST_HEAD(name) \struct list_head name = LIST_HEAD_INIT(name)static inline void __list_add(struct list_head* new_,struct list_head* prev,struct list_head* next){next->prev = new_;new_->next = next;new_->prev = prev;prev->next = new_;}static inline void list_add(struct list_head* new_, struct list_head* head){__list_add(new_, head, head->next);}static inline void list_add_tail(struct list_head* new_, struct list_head* head){__list_add(new_, head->prev, head);}static inline void __list_del(struct list_head* prev, struct list_head* next){next->prev = prev;prev->next = next;}static inline void list_del(struct list_head* entry){__list_del(entry->prev, entry->next);}typedef struct _user {char name[11];char sex[11];int age;struct list_head mylist;//自定义结构体里保存双向循环链表头结点}user;typedef struct _records {char name[20];int type;struct list_head mylist;//自定义结构体里保存双向循环链表头结点}records;int main(){//LIST_HEAD(header_task);//初始化头结点struct list_head header_task1 = {&(header_task1), &(header_task1) };struct list_head header_task2 = {&(header_task2), &(header_task2) };user u1 = {"张麻子", "男", 40 };user u2 = {"牛魔王", "男", 36 };user u3 = {"蜘蛛精", "女", 28 };records r1 = {"张麻子", 1};records r2 = {"蜘蛛精", 2};records r3 = {"牛魔王", 1};//新建struct list_head* pos1;struct list_head* pos2;user* u;records* r;//头插法list_add(&u1.mylist, &header_task1);list_add(&u2.mylist, &header_task1);list_add(&u3.mylist, &header_task1);list_add(&r1.mylist, &header_task2);list_add(&r2.mylist, &header_task2);list_add(&r3.mylist, &header_task2);//list_for_each(pos1, &header_task1) {// u = container_of(pos1, user, mylist);// printf("data is %d\n", u->age);//}for (pos1 = (&header_task1)->next; pos1 != (&header_task1); pos1 = pos1->next){//u = container_of(pos1, user, mylist);//u = ((user*)(((char*)pos1) - (int)(&(((user*)0)->mylist))));//u = (user*)((int)pos1 - sizeof(user) + sizeof((((user*)0)->mylist)));//&((user*)0)->mylist;//->优先级高于&u = (user*)((int)pos1 - (int)&((user*)0)->mylist);printf("data is %d\n", u->age);}printf("----------\n");list_del(&u2.mylist);list_for_each(pos1, &header_task1) {u = container_of(pos1, user, mylist);printf("data is %d\n", u->age);}printf("Hello World!\n");return 0;}

运行结果:

data is 28data is 36data is 40----------data is 28data is 40Hello World!

C语言 泛型链表 如何计算(结构体中各元素)相对内存地址?(字节对齐 结构体对齐)offsetof()函数 ( (struct X*)0 ) -> Y)语法(匿名结构体)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。