C语言之队列,环形数组-比链表容易多了

环形队列实现

 

①定义一个结构体:

typedef struct
{
    u16 Head;           
    u16 Tail;
    u16 Lenght;
    u8 Ring_Buff[RINGBUFF_LEN];
}RingBuff_t;
RingBuff_t ringBuff;//创建一个ringBuff的缓冲区


②初始化结构体相关信息:使得我们的环形缓冲区是头尾相连的,并且里面没有数据,也就是空的队列。

void RingBuff_Init(void)
{
   //初始化相关信息
   ringBuff.Head = 0;
   ringBuff.Tail = 0;
   ringBuff.Lenght = 0;
}

初始化效果如下:



写入环形缓冲区的代码实现:

u8 Write_RingBuff(u8 data)
{
   if(ringBuff.Lenght >= RINGBUFF_LEN) //判断缓冲区是否已满
    {
      return FLASE;
    }
    ringBuff.Ring_Buff[ringBuff.Tail]=data;
//    ringBuff.Tail++;
    ringBuff.Tail = (ringBuff.Tail+1)%RINGBUFF_LEN;//防止越界非法访问
    ringBuff.Lenght++;
    return TRUE;
}

 

ringBuff.Tail++; 

ringBuff.Tail = (ringBuff.Tail+1)%RINGBUFF_LEN;

注意 区别!

读取缓冲区的数据的代码实现:

u8 Read_RingBuff(u8 *rData)
{
   if(ringBuff.Lenght == 0)//判断非空
    {
       return FLASE;
    }
   *rData = ringBuff.Ring_Buff[ringBuff.Head];//先进先出FIFO,从缓冲区头出
//   ringBuff.Head++;
   ringBuff.Head = (ringBuff.Head+1)%RINGBUFF_LEN;//防止越界非法访问
   ringBuff.Lenght--;
   return TRUE;
}

对于读写操作需要注意的地方有两个:

1:判断队列是否为空或者满,如果空的话,是不允许读取数据的,返回FLASE。如果是满的话,也是不允许写入数据的,避免将已有数据覆盖掉。那么如果处理的速度赶不上接收的速度,可以适当增大缓冲区的大小,用空间换取时间。

2:防止指针越界非法访问,程序有说明,需要使用者对整个缓冲区的大小进行把握。


那么在串口接收函数中:

void USART1_IRQHandler(void)   
{
   if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断
          {
           USART_ClearITPendingBit(USART1,USART_IT_RXNE);       //清楚标志位
           Write_RingBuff(USART_ReceiveData(USART1));      //读取接收到的数据
       }
}


    当然,我们完全可以用空闲中断与DMA传输,效率更高


参考:杰杰https://blog.csdn.net/jiejiemcu/article/details/80563422


在 C 语言中,环形链表是一种特殊的链表结构,它与普通链表的区别在于,环形链表的最后一个节点指向链表的头节点,形成一个环。 环形链表的节点结构通常包含两个成员:一个数据域,用于存储节点的数据;一个指针域,用于指向下一个节点。例如,以下是一个简单的环形链表节点结构的定义: ``` struct Node { int data; struct Node* next; }; ``` 创建一个环形链表的过程与创建普通链表类似,只需要在最后一个节点的指针域中指向头节点即可。例如,以下是一个创建环形链表的函数: ``` struct Node* createCircularLinkedList(int data[], int n) { struct Node* head = NULL; struct Node* tail = NULL; for (int i = 0; i < n; i++) { struct Node* node = (struct Node*)malloc(sizeof(struct Node)); node->data = data[i]; node->next = NULL; if (head == NULL) { head = node; } else { tail->next = node; } tail = node; } tail->next = head; // 将最后一个节点的指针指向头节点,形成环 return head; } ``` 在环形链表中,遍历链表需要注意判断是否到达了头节点,否则将会死循环。例如,以下是一个遍历环形链表的函数: ``` void traverseCircularLinkedList(struct Node* head) { struct Node* current = head; do { printf("%d ", current->data); current = current->next; } while (current != head); } ``` 环形链表的应用场景与普通链表类似,例如用于实现循环队列、循环缓冲区等数据结构。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值