Orx引擎中单链表实现的一个小技巧

猿并不一定实现过单链表,但学过数据结构的猿一定实现过单链表。一般的,链表的结构定义是这样的简陋版链表,自己实现的,仅供参考,更专业版的可以看glib库或Linux内核里的。但是,Orx的作者实现的单链表就有点另类了,可以看这位博主写的介绍链接。这里就不重复内容了,只是写个例子体验下该技巧:

/* wtl_test.c */
#include <stdio.h>
#include <malloc.h>

int main(int argc, char* argv[])
{
    // 随便声明一个结构体
    typedef struct _wtlFOO {
        int a; // 内容可以随意,这里用int型的举例
    } wtlFOO;
    // 再声明一个
    typedef struct _wtlBAR {
        wtlFOO* foo; // 该变量的声明一定要放开头,后面的类型强制转换要用到
        int b; // 再随便加个类型的数据,也是用int举例
    } wtlBAR;

    // 定义一个二级指针,二级指针存放的是一级指针的地址,一级指针存放的是普通变量的地址,普通变量的地址上存放着内容
    wtlFOO** foo = NULL; // 后面需要通过foo这个变量访问bar中的内容
    // 为bar分配一块空间,这样,bar指向的地址才能存放内容
    wtlBAR* bar = malloc(sizeof(wtlBAR));

    // bar指向的地址,这个空间中的b区域存放一个7
    bar->b = 7;
    // foo这个二级指针指向了bar中的foo这个一级指针的地址,而不是wtlFOO类型变量的地址
    // 为bar分配空间的时候并没有为bar中的foo分配空间,不要漏了 & 符号,否则出错
    foo = &(bar->foo);
    // *foo就是bar中的foo这个一级指针了,为其分配一块空间
    *foo = malloc(sizeof(wtlFOO));
    // *foo指向的地址,这个空间中的区域存放一个9
    (*foo)->a = 9;

    // 技巧的体现就在下面这行了,foo本来是个wtlFOO类型的二级指针,存放的是对应类型的
    // 一级指针的地址,这个空间中并没有b这个区域。
    // 但是代码是没有错的。原理是,foo指向了bar中的foo的地址,该地址也是bar的首地址
    // 因为bar的foo是声明在开头的。这样得到bar的首地址后,将其强制转换成wtlBAR类型
    // 的指针,于是我们就得到了bar这块空间的信息了,因此可以访问空间中的b区域的内容了
    printf("%d\n", ((wtlBAR*)foo)->b);
    // 这句没什么特别的,只是a的值是通过foo这个二级指针赋值
    printf("%d\n", bar->foo->a);

    return 0;
}

最后再总结下前面的代码。一般的,指针只能指向对应类型(指变量类型一样)的地址,因此,我们所看到的链表都是用相同类型的next指针指向下一个节点。其实类型不一样,只要所占的字节数一样,再通过强制类型转换,指针就可以指向它了。这个技巧的其中一个用法就是Orx中链表的实现了。只要一个用来存储数据的节点的struct的开头包含另一个struct指针(该指针就是用作链表中的‘链’,且该指针的类型并不需要和节点相同),就可以形成链表。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值