一、概述
队列具有先进先出的规则FIFO(First In First Out),在实际应用中,用做数据的缓冲,任务间的通讯。
二、队列初探
2.1 队列数据类型结构体
队列相关的数据以及说明
typedef struct
{
uint8_t *u8_buf; /* 存放数据数组指针 */
uint16_t u16_len; /* 队列长度 */
uint16_t u16_front; /* 队列头索引(写) */
uint16_t u16_rear; /* 队列尾索引(读) */
}ring_queue_u8_t;
大家如果以读写的方式可能能更好的理解队列的出队与入队。
2.2 队列空判断
对于出队来说,判断队列空是必不可少的,如果是你,你会怎么定义队空,如下是队空的定义:
if( rq->u16_front == rq->u16_rear )/*头(写)指针索引和尾(读)指针索引相等,则判定为队列空*/
2.3 队列满判断
对于入队来说,判断队列满是必不可少的,如下是队满的定义:
/*头(写)指针 加 1 ,在进行取余,结果等于尾(读)指针*/
if( (rq->u16_front +1)% rq->u16_len == rq->u16_rear )
2.2.1 队列未溢出
未溢出情况下,示意图:
2.2.2 队列溢出
取余是为了加1以后,防止索引溢出
三、队列实现
3.1 队列初始化
void v_ring_queue_init(
ring_queue_u8_t *rq,
uint8_t *u8_buf,
uint16_t u16_len,
uint16_t u16_front,
uint16_t u16_rear)
{
rq->u8_buf = u8_buf ;
rq->u16_len = u16_len;
rq->u16_front = u16_front;
rq->u16_rear = u16_rear;
}
3.2 入队
/*
\brief:入队
\param[in]:
\args:rq-结构体指针ring_queue_u8_t
\args:value-入队数据
\return:(uint8_t)
\1:出队失败(队列满)
\0:出队成功
*/
uint8_t u8_ring_queue_input(ring_queue_u8_t *rq, uint8_t value)
{
if( (rq->u16_front +1)% rq->u16_len == rq->u16_rear )
{
return 1 ;
}
rq->u8_buf[rq->u16_front] = value;
rq->u16_front ++;
rq->u16_front %= rq->u16_len ;
return 0;
}
3.3 出队
/*
\brief:出队
\param[in]:
\args:rq-结构体指针ring_queue_u8_t
\args:value-出队数据的保存
\return:(uint8_t)
\1:出队失败(队列空)
\0:出队成功
*/
uint8_t u8_ring_queue_output(ring_queue_u8_t *rq, uint8_t *value)
{
/* */
if( rq->u16_front == rq->u16_rear )
{
return 1;
}
*value = rq->u8_buf[rq->u16_rear];
rq->u16_rear++;
rq->u16_rear %= rq->u16_len ;
return 0;
}
3.4 清空队列
void v_ring_queue_clear(ring_queue_u8_t *rq )
{
rq->u16_front = rq->u16_rear;
}
3.5 代码实现
int main()
{
ring_queue_u8_t x_rq_u8;
uint8_t buf[50];
/* */
v_ring_queue_init( &x_rq_u8, buf, 50, 0, 0);
uint8_t value = 5;
if( u8_ring_queue_input(&x_rq_u8, 10) == 0 )
{
printf("queue in success!\n");
}
else
{
printf("queue is full!\n");
}
if(u8_ring_queue_output(&x_rq_u8, &value) == 0 )
{
printf("queue out success!value:%d\n",value);
}
else
{
printf("queue is empty!\n");
}
return 0;
}