色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

C語言環形隊列的原理和特點

strongerHuang ? 來源:嵌入式Linux ? 作者:寫代碼的籃球球癡 ? 2021-05-11 13:56 ? 次閱讀

什么是環形隊列?

環形緩沖區是一個非常典型的數據結構,這種數據結構符合生產者,消費者模型,可以理解它是一個水坑,生產者不斷的往里面灌水,消費者就不斷的從里面取出水。

那就可能會有人問,既然需要灌水,又需要取出水,為什么還需要開辟一個緩沖區內存空間呢?直接把生產者水管的尾部接到消費者水管的頭部不就好了,這樣可以省空間啊。

答案是不行的,生產者生產水的速度是不知道的,消費者消費水的速度也是不知道的,如果你強制接在一起,因為生產和消費的速度不同,就非常可能存在水管爆炸的情況,你說這樣危險不危險?

音頻系統框架下,alsa就是使用環形隊列的,在生產者和消費者速度不匹配的時候,就會出現xrun的問題。

環形隊列的特點

1、數組構造環形緩沖區

假設我們用數組來構造一個環形緩存區,如下圖

59134ccc-b20d-11eb-bf61-12bb97331649.png

我們需要幾個東西來形容這個環形緩沖區,一個的讀位置,一個是寫位置,一個是環形緩沖區的長度

5928e3fc-b20d-11eb-bf61-12bb97331649.png

從圖片看,我們知道,這個環形緩沖區的讀寫位置是指向數組的首地址的,環形緩沖區的長度是 5 。

那如何判斷環形緩沖區為空呢?

如果 R == W 就是讀寫位置相同,則這個環形緩沖區為空

那如何判斷環形緩沖區滿了呢?

如果 (W - R )= Len ,則這個環形緩沖區已經滿了。

2、向環形緩沖區寫入 3個數據

寫入 3 個數據后,W 的值等于 3 了,R 還是等于 0。

3個企鵝已經排列

3、從環形緩沖區讀取2個數據

讀出兩個數據后,R = 2 了,這個時候,W還是等于 3,畢竟沒有再寫過數據了。

4、再寫入3個數據

如果 W 》 LEN 后,怎么找到最開始的位置的呢?這個就需要進行運算了,W%LEN 的位置就是放入數據的位置 ,6%5 = 1。

5、再寫入1個數據

這個時候環形隊列已經滿了,要是想再寫入數據的話,就不行了,(W - R) = 5 == LEN

代碼實現

/* 實現的最簡單的ringbuff 有更多提升空間,可以留言說明 */

#include “stdio.h”

#include “stdlib.h”

#define LEN 10

/*環形隊列結構體*/

typedef struct ring_buff{

int array[LEN];

int W;

int R;

}*ring;

/*環形隊列初始化*/

struct ring_buff * fifo_init(void)

{

struct ring_buff * p = NULL;

p = (struct ring_buff *)malloc(sizeof(struct ring_buff));

if(p == NULL)

{

printf(“fifo_init malloc error

”);

return NULL;

}

p-》W = 0;

p-》R = 0;

return p;

}

/*判斷環形隊列是否已經滿了*/

int get_ring_buff_fullstate(struct ring_buff * p_ring_buff)

{

/*如果寫位置減去讀位置等于隊列長度,就說明這個環形隊列已經滿*/

if((p_ring_buff-》W - p_ring_buff-》R) == LEN)

{

return (1);

}

else

{

return (0);

}

}

/*判斷環形隊列為空*/

int get_ring_buff_emptystate(struct ring_buff * p_ring_buff)

{

/*如果寫位置和讀的位置相等,就說明這個環形隊列為空*/

if(p_ring_buff-》W == p_ring_buff-》R)

{

return (1);

}

else

{

return (0);

}

}

/*插入數據*/

int ring_buff_insert(struct ring_buff * p_ring_buff,int data)

{

if(p_ring_buff == NULL)

{

printf(“p null

”);

return (-1);

}

if(get_ring_buff_fullstate(p_ring_buff) == 1)

{

printf(“buff is full

”);

return (-2);

}

p_ring_buff-》array[p_ring_buff-》W%LEN] = data;

p_ring_buff-》W ++;

//printf(“inset:%d %d

”,data,p_ring_buff-》W);

return (0);

}

/*讀取環形隊列數據*/

int ring_buff_get(struct ring_buff * p_ring_buff)

{

int data = 0;

if(p_ring_buff == NULL)

{

printf(“p null

”);

return (-1);

}

if(get_ring_buff_emptystate(p_ring_buff) == 1)

{

printf(“buff is empty

”);

return (-2);

}

data = p_ring_buff-》array[p_ring_buff-》R%LEN];

p_ring_buff-》R++;

return data;

}

/*銷毀*/

int ring_buff_destory(struct ring_buff * p_ring_buff)

{

if(p_ring_buff == NULL)

{

printf(“p null

”);

return (-1);

}

free(p_ring_buff);

return (0);

}

int main()

{

int i = 0;

/*定義一個環形緩沖區*/

ring pt_ring_buff = fifo_init();

/*向環形緩沖區中寫入數據*/

for(i = 0;i《10;i++)

{

ring_buff_insert(pt_ring_buff,i);

}

/*從環形緩沖區中讀出數據*/

for(i = 0;i《10;i++)

{

printf(“%d ”,ring_buff_get(pt_ring_buff));

}

/*銷毀一個環形緩沖區*/

ring_buff_destory(pt_ring_buff);

return (1);

}

599cb322-b20d-11eb-bf61-12bb97331649.png

換一個寫法,這個寫法是各種大神級別的

/* 實現的最簡單的ringbuff 有更多提升空間,可以留言說明 */

#include “stdio.h”

#include “stdlib.h”

#define LEN 64

/*環形隊列結構體*/

typedef struct ring_buff{

int array[LEN];

int W;

int R;

}*ring;

/*環形隊列初始化*/

struct ring_buff * fifo_init(void)

{

struct ring_buff * p = NULL;

p = (struct ring_buff *)malloc(sizeof(struct ring_buff));

if(p == NULL)

{

printf(“fifo_init malloc error

”);

return NULL;

}

p-》W = 0;

p-》R = 0;

return p;

}

/*判斷環形隊列是否已經滿了*/

int get_ring_buff_fullstate(struct ring_buff * p_ring_buff)

{

/*如果寫位置減去讀位置等于隊列長度,就說明這個環形隊列已經滿*/

if((p_ring_buff-》W - p_ring_buff-》R) == LEN)

{

return (1);

}

else

{

return (0);

}

}

/*判斷環形隊列為空*/

int get_ring_buff_emptystate(struct ring_buff * p_ring_buff)

{

/*如果寫位置和讀的位置相等,就說明這個環形隊列為空*/

if(p_ring_buff-》W == p_ring_buff-》R)

{

return (1);

}

else

{

return (0);

}

}

/*插入數據*/

int ring_buff_insert(struct ring_buff * p_ring_buff,int data)

{

if(p_ring_buff == NULL)

{

printf(“p null

”);

return (-1);

}

if(get_ring_buff_fullstate(p_ring_buff) == 1)

{

printf(“buff is full

”);

return (-2);

}

//p_ring_buff-》array[p_ring_buff-》W%LEN] = data;

p_ring_buff-》array[p_ring_buff-》W&(LEN -1)] = data;

p_ring_buff-》W ++;

//printf(“inset:%d %d

”,data,p_ring_buff-》W);

return (0);

}

/*讀取環形隊列數據*/

int ring_buff_get(struct ring_buff * p_ring_buff)

{

int data = 0;

if(p_ring_buff == NULL)

{

printf(“p null

”);

return (-1);

}

if(get_ring_buff_emptystate(p_ring_buff) == 1)

{

printf(“buff is empty

”);

return (-2);

}

//data = p_ring_buff-》array[p_ring_buff-》R%LEN];

data = p_ring_buff-》array[p_ring_buff-》R&(LEN -1)];

p_ring_buff-》R++;

return data;

}

/*銷毀*/

int ring_buff_destory(struct ring_buff * p_ring_buff)

{

if(p_ring_buff == NULL)

{

printf(“p null

”);

return (-1);

}

free(p_ring_buff);

return (0);

}

int main()

{

int i = 0;

/*定義一個環形緩沖區*/

ring pt_ring_buff = fifo_init();

/*向環形緩沖區中寫入數據*/

for(i = 0;i《10;i++)

{

ring_buff_insert(pt_ring_buff,i);

}

/*從環形緩沖區中讀出數據*/

for(i = 0;i《10;i++)

{

printf(“%d ”,ring_buff_get(pt_ring_buff));

}

/*銷毀一個環形緩沖區*/

ring_buff_destory(pt_ring_buff);

return (1);

}

總結

環形隊列的使用場景非常多,安卓的音頻數據讀寫,很多都用到環形隊列,我們在開發過程中使用的環形隊列肯定比我上面的那個例子要復雜的多,我這里演示的是比較簡單的功能,但是麻雀雖小,五臟俱全,希望這個麻雀讓你們了解這個數據結構。在實際項目中大展身手。

原文標題:C語言實現環形隊列的原理和方法

文章出處:【微信公眾號:strongerHuang】歡迎添加關注!文章轉載請注明出處。

責任編輯:haq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 數據
    +關注

    關注

    8

    文章

    7067

    瀏覽量

    89108
  • C語言
    +關注

    關注

    180

    文章

    7605

    瀏覽量

    136993

原文標題:C語言實現環形隊列的原理和方法

文章出處:【微信號:strongerHuang,微信公眾號:strongerHuang】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    環形器的特點和應用

    環形器是一個有單向傳輸特性的三端口器件,它表明器件從1到2,從2到3 和從3到1是導通的,反過來信號從2到1,從3到2和從1到3是隔離的。環形器是有數個端的非可逆器件。
    的頭像 發表于 11-29 16:49 ?460次閱讀
    <b class='flag-5'>環形</b>器的<b class='flag-5'>特點</b>和應用

    JavaWeb消息隊列使用指南

    在現代的JavaWeb應用中,消息隊列(Message Queue)是一種常見的技術,用于異步處理任務、解耦系統組件、提高系統性能和可靠性。 1. 消息隊列的基本概念 消息隊列是一種應用程序對應
    的頭像 發表于 11-25 09:27 ?152次閱讀

    C語言與Java語言的對比

    C語言和Java語言都是當前編程領域中的重要成員,它們各自具有獨特的優勢和特點,適用于不同的應用場景。以下將從語法特性、內存管理、跨平臺性、性能、應用領域等多個方面對
    的頭像 發表于 10-29 17:31 ?357次閱讀

    C語言與其他編程語言的比較

    C語言作為一種歷史悠久的編程語言,自其誕生以來,一直在軟件開發領域扮演著重要角色。它以其高效、靈活和可移植性強的特點,成為了系統級編程的首選語言
    的頭像 發表于 10-29 17:30 ?294次閱讀

    嵌入式環形隊列與消息隊列的實現原理

    嵌入式環形隊列,也稱為環形緩沖區或循環隊列,是一種先進先出(FIFO)的數據結構,用于在固定大小的存儲區域中高效地存儲和訪問數據。其主要特點
    的頭像 發表于 09-02 15:29 ?551次閱讀

    玩轉RT-Thread之消息隊列的應用

    不同來源的數據,確保系統的穩定性和響應速度。一、設計消息結構二、創建消息隊列在service.c文件中,我們需要創建一個消息隊列來存放這些消息,并在處理線程中接收和
    的頭像 發表于 07-23 08:11 ?624次閱讀
    玩轉RT-Thread之消息<b class='flag-5'>隊列</b>的應用

    按照這樣學習C語言,成為卷王不是夢!

    在計算機編程領域,C語言被譽為一種強大而靈活的編程語言,掌握好C語言不僅可以讓你輕松駕馭各種編程任務,還能夠為你的職業生涯打下堅實的基礎。但
    的頭像 發表于 07-06 08:04 ?325次閱讀
    按照這樣學習<b class='flag-5'>C</b><b class='flag-5'>語言</b>,成為卷王不是夢!

    PLC編程語言C語言的區別

    在工業自動化和計算機編程領域中,PLC(可編程邏輯控制器)編程語言C語言各自扮演著重要的角色。盡管兩者都是編程語言,但它們在多個方面存在顯著的區別。本文將從多個維度深入探討PLC編程
    的頭像 發表于 06-14 17:11 ?2884次閱讀

    C語言基礎-為什么要使用C

    當今最流行的 Linux 操作系統和 RDBMS(Relational Database Management System:關系數據庫管理系統) MySQL 都是使用 C 語言編寫的。
    發表于 03-25 11:20 ?451次閱讀

    plc編程語言c語言的聯系 c語言和PLC有什么區別

    PLC編程語言C語言的聯系 PLC(可編程邏輯控制器)是一種針對自動化控制系統的特殊計算機。PLC編程語言是為了控制和管理自動化生產過程中的各種設備而設計的。與之相比,
    的頭像 發表于 02-05 14:21 ?4179次閱讀

    c語言,c++,java,python區別

    C語言C++、Java和Python是四種常見的編程語言,各有優點和特點C
    的頭像 發表于 02-05 14:11 ?2429次閱讀

    vb語言c++語言的區別

    VB語言C++語言是兩種不同的編程語言,雖然它們都屬于高級編程語言,但在設計和用途上有很多區別。下面將詳細比較VB
    的頭像 發表于 02-01 10:20 ?2364次閱讀

    裸機中環形隊列與RTOS中消息隊列有何區別呢?

    環形隊列”和“消息隊列”在嵌入式領域有應用非常廣泛,相信有經驗的嵌入式軟件工程師對它們都不陌生。
    的頭像 發表于 01-26 09:38 ?720次閱讀
    裸機中<b class='flag-5'>環形</b><b class='flag-5'>隊列</b>與RTOS中消息<b class='flag-5'>隊列</b>有何區別呢?

    labview 隊列最前端插入的應用

    LabVIEW是一種用于實時測試、測量和控制系統的高級系統設計軟件。它采用了數據流編程方式,提供了一種直觀、可視化的方法來構建復雜的測試和測量應用程序。其中一個重要的功能是隊列,它可以在軟件設計中
    的頭像 發表于 01-08 11:45 ?1212次閱讀

    labview隊列有什么實際作用

    LabVIEW隊列是一種數據結構,常用于解決多任務并發處理的問題。它被廣泛應用于科學研究、工程項目和自動化控制等領域。在LabVIEW中,隊列提供了一種高效、方便的方式來處理不同任務之間的數據
    的頭像 發表于 01-05 16:42 ?1612次閱讀
    主站蜘蛛池模板: 國產麻豆AVMDXMDX| 涩涩网站在线看| 一本大道无码AV天堂欧美| 久久精品AV麻豆| 99亚偷拍自图区亚洲| 天天爽夜夜爽| 精品第一国产综合精品蜜芽| 538久久视频在线| 日韩一区二区三区视频在线观看| 国产在线成人一区二区三区| 18黄女脱内衣| 少妇两个奶头喷出奶水了怎么办 | 印度最猛性ⅹxxxxx| 年轻夫妇韩剧中文版免费观看 | 亚洲精品久久久久无码AV片软件| 老熟女重囗味GRANNYBBW| 成人在线视频免费| 一本道dvd久久综合高清免费 | 视频在线免费观看| 久久精品一区二区三区资源网| 补课H湿 1V1 PLAY| 亚洲人成无码久久久AAA片| 欧美派对xxxhdparty| 国产亚洲视频精彩在线播放| adc年龄确认大驾光临入口| 校花在公车上被内射好舒| 免费人妻无码AV不卡在线| 国产午夜伦鲁鲁| www.中文字幕在线观看| 亚洲中文久久久久久国产精品| 秋霞电影院午夜伦高清| 精品熟女少妇AV久久免费A片| 超碰在线视频地址| 永久免费在线观看视频| 天天靠天天擦天天摸| 女人18毛片| 狠狠色狠狠色综合日日91app| 白洁在线观看| 最新国产麻豆精品| 亚洲精品中文字幕制| 色婷婷99综合久久久精品|