打印
[STM32F1]

单片机循环队列C语言代码

[复制链接]
1718|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
hyh19890917|  楼主 | 2017-10-6 11:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
国庆放假在家学了郝斌的数据结构C语言,跟着视频把代码敲了出来,用了main函数基本验证了一下,代码中有问题注释出来了,本人C学的不是很好,很多基本的问题也不是想的明白,有朋友愿意的话可以一起交流.

说下单品片机串口通讯使用循环队列基本概念:

1.单片机初始化时候基本就可以初始化一个队列了,如果是带有实时OS的话,创建通讯任务时候再初始化一个队列,这样可以在销毁任务时候释放内存,(这个内存是堆内存是吧,学的不是很深入,猜的,欢迎大神指教哦)2.一般的,接收中断中调用入队函,将接收的字节放入队列,队列作为一个数据字节缓冲区,可以提供给协议解析或者其他功能函数使用,那么读取字节时候则需要调用出队函数;
3.一般的,发送中断中调用出队函数,数据帧函数或者其他功能函数将准备好的数据字节通过调用入队函数拷贝到队列中,然后在发送;

以上是个人粗浅的理解,因为没有什么实际的开发经验,也是看过别人用过的代码,理解到的粗浅的认知,望有大神指点一二~

一下是具体的代码实现:


/*

日期:2017-10-5 am.

*/
#include<stdio.h>
#include<string.h>
#include<stdbool.h>
#include<malloc.h>

#define DEBUG_PRINT 0

typedef struct Queue{
        char *pBase;
        int head;
        int tail;
        int q_length;
        int cnt;//有效元素个数
}Q_typdef,*pQ_typdef;

void Q_init(pQ_typdef q,int len);
bool Q_is_full(pQ_typdef q);
bool Q_is_empty(pQ_typdef q);
bool Q_push(pQ_typdef q, int val);//入列
bool Q_pop(pQ_typdef q,int * pVal);//出列

int  Q_valuable_cnt(pQ_typdef q);//队列有效元素个数
void Q_trvaerse(pQ_typdef q);

int main(char argc, char** argv)
{
        Q_typdef q_Massage;
        int temp = 0;
        Q_init(&q_Massage,6);
        for(int i=0; i<5; i++)//初始化消息队列只有6byte,所以只能入列5个byte
        {
                printf("%d入列\n", i+1);
                Q_push(&q_Massage, i+1);
        }
        Q_trvaerse(&q_Massage);
        for(int i=0; i<3; i++)
        {
                printf("第%d个元素",i+1);
                Q_pop(&q_Massage, &temp);
                printf(":%d出列\n",temp);
        }
        Q_trvaerse(&q_Massage);
        return 0;
}

void Q_init(pQ_typdef q, int len)
{
        q->q_length = len;
        q->pBase    = (char*)malloc(sizeof(char)*len);
        q->head     = 0;
        q->tail     = 0;
}

bool Q_is_full(pQ_typdef q)
{
        if(((q->tail+1)%q->q_length == q->head))return true;//||( q->cnt == q->q_length-1)
        else return false;
}

bool Q_is_empty(pQ_typdef q)
{
        if(q->head == q->tail || q->cnt==0)return true;
        else return false;
}

bool Q_push(pQ_typdef q,int val)
{
        if(Q_is_full(q))
        {
#if DEBUG_PRINT
                printf("队列已满,入队失败!\n");
                printf("有效元素个数%d  haed = %d  tail = %d length = %d\n",q->cnt,q->head,q->tail,q->q_length);
#endif        
                return false;//入列失败,数据丢失
        }
        
        q->pBase[q->tail] = val;
        //*(q->pBase + q->tail) = val;
        q->tail = (q->tail+1)%(q->q_length);
        q->cnt++;
        return true;
        //if(q->cnt < q->q_length)
}

bool Q_pop(pQ_typdef q,int * pVal)
{
        if(Q_is_empty(q))return false;//出列失败,队列已空
        *pVal= q->pBase[q->head];
        q->head ++;
        q->head %= q->q_length;
        //q->head = (q->head+1)%q->q_length;//可用
        //q->head = (q->head++)%q->q_length;//为什么不起作用..
        q->cnt--;
#if DEBUG_PRINT
                printf("\ncnt = %d  haed = %d  tail = %d length = %d\n",q->cnt,q->head,q->tail,q->q_length);
#endif
        return true;
}

void Q_trvaerse(pQ_typdef q)
{
        if( Q_is_empty(q) )
        {
                printf("队列空\n");
                return;
        }
        else
        {
                printf("遍历时队列的有效元素个数%d\n",q->cnt);
                int i=q->head;
                while(i != q->tail)
                {
                        printf("%d \n",q->pBase);
                        i++;
                }
                return;
        }
}

int  Q_valuable_cnt(pQ_typdef q)
{
        return q->cnt;
}





沙发
xinpian101| | 2017-10-6 11:21 | 只看该作者
指针的高级应用吗?看着都高大上

使用特权

评论回复
板凳
xinpian101| | 2017-10-6 11:22 | 只看该作者
为充分利用向量空间,克服"假溢出"现象的方法是:将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量。存储在其中的队列称为循环队列(Circular Queue)。

使用特权

评论回复
地板
zhuotuzi| | 2017-10-6 14:17 | 只看该作者
单片机的内存有限,用这种可以提高效率。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

20

主题

162

帖子

0

粉丝