void *指针的妙用
2015-05-05 来源:51hei
在看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 *时特别注意的事项。
上一篇:马踏棋盘的实现
- stm32中的NVIC_Configuration(void)函数
- STM32中断优先级void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
- STM32库函数void USART_SendData()的缺陷和解决方法
- GPIO复位函数void GPIO_DeInit(GPIO_TypeDef* GPIOx) 的理解
- STM32标准外设库函数SetSysClockTo72(void)
- STM32是怎样进入执行中断函数xxx_IRQHandler(void)的
- STM32库函数void USART_SendData的缺陷和解决方法
- C51中断(void timer1(void) interrupt 3 using 3)
- 串口中断服务函数解释USART1_IRQHandler(void)
- 深入理解void类型