最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語言隊(duì)列和應(yīng)用詳情

 更新時(shí)間:2022年03月06日 10:41:47   作者:Embedded?learner  
這篇文章主要介紹了C語言隊(duì)列和應(yīng)用詳情,文章將讓大家掌握掌握隊(duì)列的原理和作用、掌握隊(duì)列的寫法、掌握隊(duì)列在產(chǎn)品中的應(yīng)用,需要的朋友可以參考一下

1.隊(duì)列的原理

隊(duì)列原理其實(shí)就像一個(gè)管道,如果我們不斷往管道里面塞乒乓球,每個(gè)乒乓球在管道里就會排列一條隊(duì)形。先進(jìn)去的乒乓球就會先出來,這個(gè)就是隊(duì)列的先進(jìn)先出的規(guī)則。

球從左邊進(jìn)去,進(jìn)去的動作就是入列,然后進(jìn)去的球在管道里排成一個(gè)隊(duì)列,這個(gè)叫隊(duì)列緩存,說白了就是數(shù)組,那么這里存了5個(gè)球就相當(dāng)于是buff[5];這樣的意思,最右邊出來的1號球就是最早進(jìn)去的球,出來的這個(gè)動作叫出列,所以遵循了先進(jìn)先出的規(guī)則。

2.隊(duì)列的作用

隊(duì)列最主要的作用就是用來緩存數(shù)據(jù),比方說串口接收數(shù)據(jù),我們一般定義一個(gè)數(shù)組來存儲數(shù)據(jù),但是假如串口數(shù)據(jù)頻率很快,可能這個(gè)數(shù)組里存儲的數(shù)據(jù)還沒處理完,下一組串口數(shù)據(jù)又過來了,那么這時(shí)候數(shù)組里的數(shù)據(jù)就會被新數(shù)據(jù)覆蓋,導(dǎo)致老的數(shù)據(jù)丟失。像這種就可以通過隊(duì)列的方式來處理,每收到一個(gè)字節(jié)數(shù)據(jù)都先入列,然后應(yīng)用程序同步解析處理,根據(jù)隊(duì)列先進(jìn)先出的規(guī)則,那么老的數(shù)據(jù)就不會被新的數(shù)據(jù)“插隊(duì)”了。

基于這種緩存數(shù)據(jù)的技術(shù),可以靈活應(yīng)用在各種場景,比如說:

  • 1、操作系統(tǒng)的消息傳遞
  • 2、大數(shù)據(jù)處理

3.隊(duì)列程序設(shè)計(jì)思路

其實(shí)實(shí)現(xiàn)隊(duì)列的方法有很多種,但是工作原理都是一樣的,我們要編寫代碼,首先要很清楚隊(duì)列的工作原理。

  • 1、隊(duì)列緩存
  • 2、入列
  • 3、出列
  • 一個(gè)隊(duì)列基本上要有上面這三個(gè)必要的操作,那么隊(duì)列緩存就很好理解,說白了就是直接定義一個(gè)數(shù)組,數(shù)組大小就是隊(duì)列緩存的大小。入列就是把1個(gè)或者若干個(gè)數(shù)據(jù)按順序存到隊(duì)列緩存數(shù)組里,同樣出列把數(shù)據(jù)從隊(duì)列緩存里取出來。

入列和出列的原理懂了,那么應(yīng)該怎么樣用程序來實(shí)現(xiàn)呢?

4.入列

根據(jù)上文的說法,入列就是把數(shù)據(jù)存進(jìn)數(shù)組的操作,我們平時(shí)存數(shù)組一般都是buff[0]=1;這樣操作。不過在隊(duì)列中我們要考慮隊(duì)列里當(dāng)前存在多少個(gè)數(shù)據(jù)的情況,如果有數(shù)據(jù),那么我們就不能從[0]這個(gè)下標(biāo)開始入列,所以我們在入列時(shí)要考慮兩個(gè)問題:

  • 1、隊(duì)列緩存可以存儲的數(shù)組下標(biāo)位置,這個(gè)我們一般稱為隊(duì)尾。
  • 2、隊(duì)列是否已滿,如果隊(duì)列緩存滿了又有新的數(shù)據(jù)入列,該怎么處理?這里我們一般處理方式是按照時(shí)間順序,把最早入列的數(shù)據(jù)

丟棄,以新的數(shù)據(jù)替換。
第二個(gè)問題先暫時(shí)不管,先看第一個(gè)問題。根據(jù)前面學(xué)過的數(shù)組與指針,通過指針的特性,我們在用1個(gè)指針來代表隊(duì)尾,然后這個(gè)隊(duì)尾指針指向隊(duì)列緩存數(shù)組的首地址,當(dāng)入列1個(gè)數(shù)據(jù)時(shí),我們的隊(duì)尾指針就+1,這樣是不是就能夠知道當(dāng)前隊(duì)列緩存的可以存儲的地址了?

5.出列

數(shù)據(jù)入列以后自然要取出來,那么我們?nèi)〉臅r(shí)候也是有原則的,不能亂取,而是從最早入列那個(gè)數(shù)據(jù)的地址開始取,所以這個(gè)出列的數(shù)組下標(biāo)我們稱為隊(duì)頭,同樣我們可以使用指針變量來代表這個(gè)隊(duì)頭。
我們看看下面這個(gè)圖是一個(gè)出列的流程,我們這個(gè)是滿編隊(duì)的隊(duì)列,總共有1,2,3,4,5個(gè)數(shù)據(jù),那么隊(duì)頭指針指向隊(duì)列緩存首地址,接著第一個(gè)出列的就是數(shù)據(jù)1,出列后隊(duì)頭指針加1,就指向數(shù)據(jù)2的地址,那么數(shù)據(jù)2出列后,隊(duì)頭指針又加1,指向數(shù)據(jù)3的地址,以此類推,這樣就可以實(shí)現(xiàn)先進(jìn)先出的原則。

6.掌握隊(duì)列程序編寫

那么我們知道原理后就可以用程序來實(shí)現(xiàn)它了,因?yàn)橐粋€(gè)產(chǎn)品中,會有很多隊(duì)列代表不同的數(shù)據(jù),比如說消息我有一個(gè)隊(duì)列,底層串口接收我也有一個(gè)隊(duì)列,所以我們吧隊(duì)列的一些操作,比如說入列,出列的操作單獨(dú)寫成函數(shù)接口,方便程序不同區(qū)域的調(diào)用。

#include <stdio.h>
#include "Queue.h"
Queue4 KeyMsg;

int main(int argc, char *argv[])
{
?? ?unsigned char a;?
?? ?QueueEmpty(KeyMsg);/*初始化*/
?? ?printf("site:%d\r\n",sizeof(KeyMsg.Buff));?
?? ?printf("&KeyMsg=0x%x, KeyMsg.Buff=0x%x, KeyMsg.Head=0x%x, KeyMsg.Tail=0x%x\r\n",&KeyMsg,KeyMsg.Buff,KeyMsg.Head,KeyMsg.Tail);
?? ?printf("&buff[0]=0x%x, &buff[1]=0x%x, &buff[2]=0x%x, &buff[3]=0x%x \r\n",&KeyMsg.Buff[0],&KeyMsg.Buff[1],&KeyMsg.Buff[2],&KeyMsg.Buff[3]);
?? ?printf("\r\n");?
?? ?
?? ?a = 1;
?? ?QueueDataIn(KeyMsg,&a,1);/*要用哪一個(gè)隊(duì)列,要存那個(gè)數(shù)據(jù),要存多少個(gè)數(shù)據(jù)*/
?? ?printf("&KeyMsg=0x%x, KeyMsg.Buff=0x%x, KeyMsg.Head=0x%x, KeyMsg.Tail=0x%x\r\n",&KeyMsg,KeyMsg.Buff,KeyMsg.Head,KeyMsg.Tail);
?? ?printf("buff[0]=0x%x, buff[1]=0x%x, buff[2]=0x%x, buff[3]=0x%x \r\n",KeyMsg.Buff[0],KeyMsg.Buff[1],KeyMsg.Buff[2],KeyMsg.Buff[3]);
?? ?printf("\r\n");?
?? ?
?? ?a = 2;
?? ?QueueDataIn(KeyMsg,&a,1);
?? ?printf("&KeyMsg=0x%x, KeyMsg.Buff=0x%x, KeyMsg.Head=0x%x, KeyMsg.Tail=0x%x\r\n",&KeyMsg,KeyMsg.Buff,KeyMsg.Head,KeyMsg.Tail);
?? ?printf("buff[0]=0x%x, buff[1]=0x%x, buff[2]=0x%x, buff[3]=0x%x \r\n",KeyMsg.Buff[0],KeyMsg.Buff[1],KeyMsg.Buff[2],KeyMsg.Buff[3]);
?? ?printf("\r\n");?
?? ?
?? ?a = 3;
?? ?QueueDataIn(KeyMsg,&a,1);
?? ?printf("&KeyMsg=0x%x, KeyMsg.Buff=0x%x, KeyMsg.Head=0x%x, KeyMsg.Tail=0x%x\r\n",&KeyMsg,KeyMsg.Buff,KeyMsg.Head,KeyMsg.Tail);
?? ?printf("buff[0]=0x%x, buff[1]=0x%x, buff[2]=0x%x, buff[3]=0x%x \r\n",KeyMsg.Buff[0],KeyMsg.Buff[1],KeyMsg.Buff[2],KeyMsg.Buff[3]);
?? ?printf("\r\n");?
?? ?
? ? a = 4;
?? ?QueueDataIn(KeyMsg,&a,1);
?? ?printf("&KeyMsg=0x%x, KeyMsg.Buff=0x%x, KeyMsg.Head=0x%x, KeyMsg.Tail=0x%x\r\n",&KeyMsg,KeyMsg.Buff,KeyMsg.Head,KeyMsg.Tail);
?? ?printf("buff[0]=0x%x, buff[1]=0x%x, buff[2]=0x%x, buff[3]=0x%x \r\n",KeyMsg.Buff[0],KeyMsg.Buff[1],KeyMsg.Buff[2],KeyMsg.Buff[3]);
?? ?printf("\r\n");?
?? ?
?? ?a = 5;
?? ?QueueDataIn(KeyMsg,&a,1);
?? ?printf("&KeyMsg=0x%x, KeyMsg.Buff=0x%x, KeyMsg.Head=0x%x, KeyMsg.Tail=0x%x\r\n",&KeyMsg,KeyMsg.Buff,KeyMsg.Head,KeyMsg.Tail);
?? ?printf("buff[0]=0x%x, buff[1]=0x%x, buff[2]=0x%x, buff[3]=0x%x \r\n",KeyMsg.Buff[0],KeyMsg.Buff[1],KeyMsg.Buff[2],KeyMsg.Buff[3]);
?? ?printf("\r\n");?
?? ?
?? ?printf("&KeyMsg=0x%x, KeyMsg.Buff=0x%x, KeyMsg.Head=0x%x, KeyMsg.Tail=0x%x\r\n",&KeyMsg,KeyMsg.Buff,KeyMsg.Head,KeyMsg.Tail);
?? ?QueueDataOut(KeyMsg,&a);/*要用哪一個(gè)隊(duì)列,要取那個(gè)數(shù)據(jù)*/
?? ?printf("a=%d\r\n",a);?
?? ?printf("&KeyMsg=0x%x, KeyMsg.Buff=0x%x, KeyMsg.Head=0x%x, KeyMsg.Tail=0x%x\r\n",&KeyMsg,KeyMsg.Buff,KeyMsg.Head,KeyMsg.Tail);
?? ?printf("buff[0]=0x%x, buff[1]=0x%x, buff[2]=0x%x, buff[3]=0x%x \r\n",KeyMsg.Buff[0],KeyMsg.Buff[1],KeyMsg.Buff[2],KeyMsg.Buff[3]);
?? ?printf("\r\n");?
?? ?
?? ?return 0;
}

queue.c代碼

void S_QueueEmpty(unsigned char **Head,unsigned char **Tail,unsigned char *pBuff)
{
?? ?*Head = pBuff;
?? ?*Tail = pBuff;?
}

void S_QueueDataIn(unsigned char **Head,unsigned char **Tail,unsigned char *pBuff,unsigned char Len,unsigned char *pData,unsigned char DataLen)
{
?? ?unsigned char num;
?? ?//關(guān)閉中斷?
?? ?for(num=0; num < DataLen; num++,pData++)
?? ?{?? ?
?? ??? ?**Tail = *pData;?? ??? ?//這里把數(shù)據(jù)入列?
?? ??? ?(*Tail)++;?? ??? ??? ??? ?//隊(duì)尾指針加1
?? ? ?? ?if(*Tail == pBuff+Len)
?? ? ?? ?{
?? ? ?? ??? ?*Tail = pBuff;?
?? ? ?? ?}
?? ??? ?if(*Tail == *Head)
?? ??? ?{
?? ??? ??? ?
?? ??? ??? ?if(++(*Head) == pBuff+Len)
?? ??? ??? ?{
?? ??? ??? ??? ?*Head = pBuff;?? ?
?? ??? ??? ?}
?? ??? ?}
?? ?}
?? ?//打開中斷?
}

unsigned char S_QueueDataOut(unsigned char **Head,unsigned char **Tail,unsigned char *pBuff,unsigned char Len,unsigned char *pData)
{
?? ?unsigned char status;
?? ?//關(guān)閉中斷?
?? ?status = 0;
?? ?if(*Head != *Tail)
?? ?{
?? ??? ?*pData = **Head;
?? ??? ?status = 1;
?? ??? ?if(++(*Head) == pBuff+Len)
?? ??? ?{
?? ??? ??? ?*Head = pBuff;
?? ??? ?}
?? ?}
?? ?//恢復(fù)中斷?
?? ?return status;
}

unsigned short S_QueueDataLen(unsigned char **Head,unsigned char **Tail,unsigned char *pBuff,unsigned char Len)
{
?? ?if(*Tail > *Head)
?? ?{
?? ??? ?return *Tail-*Head;
?? ?}
?? ?if(*Tail < *Head)
?? ?{
?? ??? ?return *Tail+Len-*Head;?? ?
?? ?}
}

queue.h代碼

#ifndef _QUEUE_H_
#define _QUEUE_H_

extern void S_QueueEmpty(unsigned char **Head,unsigned char **Tail,unsigned char *pBuff);
extern void S_QueueDataIn(unsigned char **Head,unsigned char **Tail,unsigned char *pBuff,unsigned char Len,unsigned char *pData,unsigned char DataLen);
extern unsigned char S_QueueDataOut(unsigned char **Head,unsigned char **Tail,unsigned char *pBuff,unsigned char Len,unsigned char *pData);?
extern unsigned short S_QueueDataLen(unsigned char **Head,unsigned char **Tail,unsigned char *pBuff,unsigned char Len);?

#define QueueEmpty(x) ?S_QueueEmpty((unsigned char **)&(x).Head,(unsigned char **)&(x).Tail,(unsigned char *)(x).Buff)

#define QueueDataIn(x,y,z) S_QueueDataIn((unsigned char **)&(x).Head,(unsigned char **)&(x).Tail,(unsigned char *)&(x).Buff,sizeof((x).Buff),y,z)
#define QueueDataOut(x,y) ?S_QueueDataOut((unsigned char **)&(x).Head,(unsigned char **)&(x).Tail,(unsigned char *)&(x).Buff,sizeof((x).Buff),y)
#define QueueDataLen(x) ?? ?S_QueueDataLen((unsigned char **)&(x).Head,(unsigned char **)&(x).Tail,(unsigned char *)&(x).Buff,sizeof((x).Buff))
?
typedef struct
{
?? ?unsigned char *Head; ?? ?//隊(duì)頭指針,用來出列用的?
?? ?unsigned char *Tail; ?? ?//隊(duì)尾指針,用來入列用的?
?? ?unsigned char Buff[4];?? ?//隊(duì)列緩存?
}Queue4;

typedef struct
{
?? ?unsigned char *Head; ?? ?//隊(duì)頭指針,用來出列用的?
?? ?unsigned char *Tail; ?? ?//隊(duì)尾指針,用來入列用的?
?? ?unsigned char Buff[128];?? ?//隊(duì)列緩存?
}Queue128;

typedef struct
{
?? ?unsigned char *Head; ?? ?//隊(duì)頭指針,用來出列用的?
?? ?unsigned char *Tail; ?? ?//隊(duì)尾指針,用來入列用的?
?? ?unsigned char Buff[512];?? ?//隊(duì)列緩存?
}Queue512;
#endif

7.隊(duì)列的應(yīng)用

串口的應(yīng)用:

如果產(chǎn)品有兩個(gè)功能,一個(gè)功能需要燈一秒閃1次,另一個(gè)功能需要燈1秒閃2次,在功能切換很快的情況下,需要功能正常并且燈的閃爍正常,那么就需要隊(duì)列了。

到此這篇關(guān)于C語言隊(duì)列和應(yīng)用詳情的文章就介紹到這了,更多相關(guān)C語言隊(duì)列和應(yīng)用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一起來了解一下C++的結(jié)構(gòu)體?struct

    一起來了解一下C++的結(jié)構(gòu)體?struct

    這篇文章主要為大家詳細(xì)介紹了C++的結(jié)構(gòu)體struct,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • C語言數(shù)據(jù)結(jié)構(gòu)線性表教程示例詳解

    C語言數(shù)據(jù)結(jié)構(gòu)線性表教程示例詳解

    這篇文章主要為大家介紹了C語言數(shù)據(jù)結(jié)構(gòu)線性表的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-02-02
  • C++中vector類的一些簡單實(shí)現(xiàn)

    C++中vector類的一些簡單實(shí)現(xiàn)

    C++中的std::vector是一個(gè)動態(tài)數(shù)組(也被稱為可變大小數(shù)組)的容器類,它是C++標(biāo)準(zhǔn)庫提供的其中一種容器類,提供了方便的操作和管理動態(tài)數(shù)組的功能,本文就給大家介紹了C++中vector類的簡單實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2023-08-08
  • C++ 實(shí)現(xiàn)對象的克隆 (多種方法)

    C++ 實(shí)現(xiàn)對象的克隆 (多種方法)

    在 C++ 中,對象的克隆通常通過實(shí)現(xiàn)一個(gè)克隆接口來完成,該接口允許創(chuàng)建對象的深拷貝,下面是實(shí)現(xiàn)對象克隆的幾種方法,具體取決于需要克隆的對象類型和上下文,感興趣的朋友跟隨小編一起看看吧
    2024-12-12
  • 數(shù)據(jù)結(jié)構(gòu)之歸并排序的實(shí)例詳解

    數(shù)據(jù)結(jié)構(gòu)之歸并排序的實(shí)例詳解

    這篇文章主要介紹了數(shù)據(jù)結(jié)構(gòu)之歸并排序的實(shí)例詳解的相關(guān)資料,這里對歸并排序進(jìn)行詳細(xì)介紹,需要的朋友可以參考下
    2017-08-08
  • C語言實(shí)現(xiàn)修改文本文件中特定行的實(shí)現(xiàn)代碼

    C語言實(shí)現(xiàn)修改文本文件中特定行的實(shí)現(xiàn)代碼

    最近由于項(xiàng)目需要實(shí)現(xiàn)修改文件的功能,所以,博主認(rèn)真查閱了一些資料,但是,很遺憾,并沒有太多的收獲
    2013-06-06
  • C++中Boost的轉(zhuǎn)換函數(shù)

    C++中Boost的轉(zhuǎn)換函數(shù)

    這篇文章介紹了C++中Boost的轉(zhuǎn)換函數(shù),文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • Qt利用QJson實(shí)現(xiàn)解析數(shù)組的示例詳解

    Qt利用QJson實(shí)現(xiàn)解析數(shù)組的示例詳解

    這篇文章主要為大家詳細(xì)介紹了Qt如何利用QJson實(shí)現(xiàn)解析數(shù)組功能,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Qt有一定幫助,需要的小伙伴可以了解一下
    2022-10-10
  • C語言中數(shù)組的一些基本知識小結(jié)

    C語言中數(shù)組的一些基本知識小結(jié)

    這篇文章主要介紹了C語言中數(shù)組的一些基本知識小結(jié),其中重點(diǎn)是對于數(shù)組的內(nèi)存分配相關(guān)方面的知識整理,需要的朋友可以參考下
    2016-04-04
  • 淺談VC中預(yù)編譯的頭文件放那里的問題分析

    淺談VC中預(yù)編譯的頭文件放那里的問題分析

    本篇文章是對VC中預(yù)編譯的頭文件放那里的問題進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05

最新評論

龙口市| 宣化县| 酉阳| 射阳县| SHOW| 北流市| 金华市| 高邑县| 河北区| 永川市| 阳春市| 富民县| 湛江市| 静海县| 北票市| 长葛市| 宁明县| 伊春市| 南投县| 酒泉市| 沾益县| 大悟县| 临猗县| 随州市| 晋宁县| 沂源县| 廉江市| 磐安县| 东平县| 将乐县| 龙泉市| 黎城县| 玉环县| 客服| 玉溪市| 乐都县| 聊城市| 越西县| 南康市| 丰台区| 雷州市|