单片机
返回首页

void *指针的妙用

2015-05-05 来源:51hei

在阅读源码的过程中,我发现很多的代码中都采用了链表,链表的也是非常有意义的一种。有我们在C语言中使用的那种数据嵌套指针的方式。也有在linux中将链表作为一个单独的对象,然后将这个对象嵌入到不同的对象中,然后根据container_of()得到对应的对象指针。这些方式都是常用的方式之一。

在看uC/OS-II中我阅读源码时发现其中竟然很少有关于链表的操作。开始也没有仔细的去分析原因,我甚至认为位图的方式取代了链表。因为uC/OS-II基本上可以任务是基于数组等静态内存分布的方式,全局变量的形式可以通过位图简单的链接在一起。
但是在阅读事件标志组的过程中我发现其中还是存在很多关于链表的操作的,比如很多的如何将事件标志节点链接起来,但是分析源码并没有

 

    typedef struct {                            /* Event Flag Wait List Node */
        void *OSFlagNodeNext; /* Pointer to next NODE in wait list */
        void *OSFlagNodePrev; /* Pointer to previous NODE in wait list */
        void *OSFlagNodeTCB; /* Pointer to TCB of waiting task */
        void *OSFlagNodeFlagGrp; /* Pointer to Event Flag Group */
        OS_FLAGS OSFlagNodeFlags; /* Event flag to wait on */
        INT8U OSFlagNodeWaitType; /* Type of wait: */
                                                /* OS_FLAG_WAIT_AND */
                                                /* OS_FLAG_WAIT_ALL */
                                                /* OS_FLAG_WAIT_OR */
                                                /* OS_FLAG_WAIT_ANY */
    } OS_FLAG_NODE;
    #endif

从上面的代码可以发现并没有使用OS_FLAG_NODE的指针形式,而是采用了void *的指针形式,结合具体的实现过程我发现这样的定义方式确实相比我们之前传统的定义方式存在很多的优点,首先这种连接方式比传统的链接方式更加的灵活多变,并一定指向的内容就是自己定义的这种结构体,因为void *这种全能的指针形式扩大了对不同类型的链接能力,使得链表的优势更加的明显。

 

    pnode->OSFlagNodeNext = pgrp->OSFlagWaitList; /* Add node at beginning of event flag wait list */
        pnode->OSFlagNodePrev = (void *)0;
        pnode->OSFlagNodeFlagGrp = (void *)pgrp; /* Link to Event Flag Group */
        pnode_next = (OS_FLAG_NODE *)pgrp->OSFlagWaitList;
        if (pnode_next != (void *)0) { /* Is this the first NODE to insert? */
            pnode_next->OSFlagNodePrev = pnode; /* No, link in doubly linked list */
        }
        pgrp->OSFlagWaitList = (void *)pnode;

上面是我从源码中复制出来的部分代码其中就有这种链表的操作方式,可以发现这种void*的类型扩大了链接对象的范围。但同样需要注意的时,在编写代码的过程中需要强制类型转换,也就是链接到链表中时需要转换为void *类型,而当弹出链表以后又需要转换成数据本身的结构类型,这可能导致一些问题的产生。但是void *类型的指针确实能够实现不同对象之间的链接关系。这就类似于在linux中的嵌入式链表非常的类似。
强制类型转换是在使用void *时特别注意的事项。

进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 光控音效发生器电路

  • 如何利用ESP8266制作一个简单的四轴飞行器

  • 一个简单的警笛电路图

  • 基于IC555的可变PWM振荡器电路

  • 分享一个电网倾角计电路

  • 一种构建12V和230V双直流电源的简单方法

    相关电子头条文章