C語(yǔ)言中怎么實(shí)現(xiàn)一個(gè)環(huán)形隊(duì)列

C語(yǔ)言中怎么實(shí)現(xiàn)一個(gè)環(huán)形隊(duì)列,相信很多沒(méi)有經(jīng)驗(yàn)的人對(duì)此束手無(wú)策,為此本文總結(jié)了問(wèn)題出現(xiàn)的原因和解決方法,通過(guò)這篇文章希望你能解決這個(gè)問(wèn)題。

成都創(chuàng)新互聯(lián)"三網(wǎng)合一"的企業(yè)建站思路。企業(yè)可建設(shè)擁有電腦版、微信版、手機(jī)版的企業(yè)網(wǎng)站。實(shí)現(xiàn)跨屏營(yíng)銷(xiāo),產(chǎn)品發(fā)布一步更新,電腦網(wǎng)絡(luò)+移動(dòng)網(wǎng)絡(luò)一網(wǎng)打盡,滿(mǎn)足企業(yè)的營(yíng)銷(xiāo)需求!成都創(chuàng)新互聯(lián)具備承接各種類(lèi)型的網(wǎng)站制作、成都網(wǎng)站建設(shè)項(xiàng)目的能力。經(jīng)過(guò)10多年的努力的開(kāi)拓,為不同行業(yè)的企事業(yè)單位提供了優(yōu)質(zhì)的服務(wù),并獲得了客戶(hù)的一致好評(píng)。

 

什么是環(huán)形隊(duì)列?

環(huán)形緩沖區(qū)是一個(gè)非常典型的數(shù)據(jù)結(jié)構(gòu),這種數(shù)據(jù)結(jié)構(gòu)符合生產(chǎn)者,消費(fèi)者模型,可以理解它是一個(gè)水坑,生產(chǎn)者不斷的往里面灌水,消費(fèi)者就不斷的從里面取出水。

C語(yǔ)言中怎么實(shí)現(xiàn)一個(gè)環(huán)形隊(duì)列  

那就可能會(huì)有人問(wèn),既然需要灌水,又需要取出水,為什么還需要開(kāi)辟一個(gè)緩沖區(qū)內(nèi)存空間呢?直接把生產(chǎn)者水管的尾部接到消費(fèi)者水管的頭部不就好了,這樣可以省空間啊。

C語(yǔ)言中怎么實(shí)現(xiàn)一個(gè)環(huán)形隊(duì)列  

答案是不行的,生產(chǎn)者生產(chǎn)水的速度是不知道的,消費(fèi)者消費(fèi)水的速度也是不知道的,如果你強(qiáng)制接在一起,因?yàn)樯a(chǎn)和消費(fèi)的速度不同,就非??赡艽嬖谒鼙ǖ那闆r,你說(shuō)這樣危險(xiǎn)不危險(xiǎn)?

C語(yǔ)言中怎么實(shí)現(xiàn)一個(gè)環(huán)形隊(duì)列  

 

在音頻系統(tǒng)框架下,alsa就是使用環(huán)形隊(duì)列的,在生產(chǎn)者和消費(fèi)者速度不匹配的時(shí)候,就會(huì)出現(xiàn)xrun的問(wèn)題。

 

環(huán)形隊(duì)列的特點(diǎn)

 

1、數(shù)組構(gòu)造環(huán)形緩沖區(qū)

假設(shè)我們用數(shù)組來(lái)構(gòu)造一個(gè)環(huán)形緩存區(qū),如下圖

C語(yǔ)言中怎么實(shí)現(xiàn)一個(gè)環(huán)形隊(duì)列

我們需要幾個(gè)東西來(lái)形容這個(gè)環(huán)形緩沖區(qū),一個(gè)的讀位置,一個(gè)是寫(xiě)位置,一個(gè)是環(huán)形緩沖區(qū)的長(zhǎng)度

C語(yǔ)言中怎么實(shí)現(xiàn)一個(gè)環(huán)形隊(duì)列

從圖片看,我們知道,這個(gè)環(huán)形緩沖區(qū)的讀寫(xiě)位置是指向數(shù)組的首地址的,環(huán)形緩沖區(qū)的長(zhǎng)度是 5 。

那如何判斷環(huán)形緩沖區(qū)為空呢?

如果 R == W  就是讀寫(xiě)位置相同,則這個(gè)環(huán)形緩沖區(qū)為空

那如何判斷環(huán)形緩沖區(qū)滿(mǎn)了呢?

如果 (W - R )= Len ,則這個(gè)環(huán)形緩沖區(qū)已經(jīng)滿(mǎn)了。

 

2、向環(huán)形緩沖區(qū)寫(xiě)入 3個(gè)數(shù)據(jù)

C語(yǔ)言中怎么實(shí)現(xiàn)一個(gè)環(huán)形隊(duì)列  

寫(xiě)入 3 個(gè)數(shù)據(jù)后,W 的值等于 3 了,R 還是等于 0。

3個(gè)企鵝已經(jīng)排列

 

3、從環(huán)形緩沖區(qū)讀取2個(gè)數(shù)據(jù)

C語(yǔ)言中怎么實(shí)現(xiàn)一個(gè)環(huán)形隊(duì)列  

讀出兩個(gè)數(shù)據(jù)后,R = 2 了,這個(gè)時(shí)候,W還是等于 3,畢竟沒(méi)有再寫(xiě)過(guò)數(shù)據(jù)了。

 

4、再寫(xiě)入3個(gè)數(shù)據(jù)

C語(yǔ)言中怎么實(shí)現(xiàn)一個(gè)環(huán)形隊(duì)列  

如果 W > LEN 后,怎么找到最開(kāi)始的位置的呢?這個(gè)就需要進(jìn)行運(yùn)算了,W%LEN 的位置就是放入數(shù)據(jù)的位置 ,6%5 = 1。

 

5、再寫(xiě)入1個(gè)數(shù)據(jù)

C語(yǔ)言中怎么實(shí)現(xiàn)一個(gè)環(huán)形隊(duì)列  

這個(gè)時(shí)候環(huán)形隊(duì)列已經(jīng)滿(mǎn)了,要是想再寫(xiě)入數(shù)據(jù)的話(huà),就不行了,(W - R) = 5 == LEN

 

代碼實(shí)現(xiàn)

/* 實(shí)現(xiàn)的最簡(jiǎn)單的ringbuff 有更多提升空間,可以留言說(shuō)明 */
#include "stdio.h"
#include "stdlib.h"

#define LEN 10

/*環(huán)形隊(duì)列結(jié)構(gòu)體*/
typedef struct ring_buff{
int array[LEN];
int W;
int R;
}*ring;

/*環(huán)形隊(duì)列初始化*/
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\n");
  return NULL;
}
p->W = 0;
p->R = 0;
return p;
}

/*判斷環(huán)形隊(duì)列是否已經(jīng)滿(mǎn)了*/
int get_ring_buff_fullstate(struct ring_buff * p_ring_buff)
{
/*如果寫(xiě)位置減去讀位置等于隊(duì)列長(zhǎng)度,就說(shuō)明這個(gè)環(huán)形隊(duì)列已經(jīng)滿(mǎn)*/
if((p_ring_buff->W - p_ring_buff->R) == LEN)
{
return (1);
}
else
{
return (0);
}
}

/*判斷環(huán)形隊(duì)列為空*/
int get_ring_buff_emptystate(struct ring_buff * p_ring_buff)
{
/*如果寫(xiě)位置和讀的位置相等,就說(shuō)明這個(gè)環(huán)形隊(duì)列為空*/
if(p_ring_buff->W == p_ring_buff->R)
{
return (1);
}
else
{
return (0);
}
}
/*插入數(shù)據(jù)*/
int ring_buff_insert(struct ring_buff * p_ring_buff,int data)
{
if(p_ring_buff == NULL)
{
  printf("p null\n");
  return (-1);
}

if(get_ring_buff_fullstate(p_ring_buff) == 1)
{
printf("buff is full\n");
return (-2);
}

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

p_ring_buff->W ++;
//printf("inset:%d %d\n",data,p_ring_buff->W);
return (0);
}

/*讀取環(huán)形隊(duì)列數(shù)據(jù)*/
int ring_buff_get(struct ring_buff * p_ring_buff)
{
int data = 0;

if(p_ring_buff == NULL)
{
  printf("p null\n");
  return (-1);
}

if(get_ring_buff_emptystate(p_ring_buff) == 1)
{
printf("buff is empty\n");
return (-2);
}

data = p_ring_buff->array[p_ring_buff->R%LEN];
p_ring_buff->R++;
return data;
}

/*銷(xiāo)毀*/
int ring_buff_destory(struct ring_buff * p_ring_buff)
{
if(p_ring_buff == NULL)
{
  printf("p null\n");
  return (-1);
}

free(p_ring_buff);

return (0);
}

int main()
{
int i = 0;

/*定義一個(gè)環(huán)形緩沖區(qū)*/
ring pt_ring_buff = fifo_init();

/*向環(huán)形緩沖區(qū)中寫(xiě)入數(shù)據(jù)*/
for(i = 0;i<10;i++)
{
ring_buff_insert(pt_ring_buff,i);
}

/*從環(huán)形緩沖區(qū)中讀出數(shù)據(jù)*/
for(i = 0;i<10;i++)
{
printf("%d ",ring_buff_get(pt_ring_buff));
}

/*銷(xiāo)毀一個(gè)環(huán)形緩沖區(qū)*/
ring_buff_destory(pt_ring_buff);

return (1);
}
 

C語(yǔ)言中怎么實(shí)現(xiàn)一個(gè)環(huán)形隊(duì)列

換一個(gè)寫(xiě)法,這個(gè)寫(xiě)法是各種大神級(jí)別的


/* 實(shí)現(xiàn)的最簡(jiǎn)單的ringbuff 有更多提升空間,可以留言說(shuō)明 */
#include "stdio.h"
#include "stdlib.h"

#define LEN 64

/*環(huán)形隊(duì)列結(jié)構(gòu)體*/
typedef struct ring_buff{
int array[LEN];
int W;
int R;
}*ring;

/*環(huán)形隊(duì)列初始化*/
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\n");
  return NULL;
}
p->W = 0;
p->R = 0;
return p;
}

/*判斷環(huán)形隊(duì)列是否已經(jīng)滿(mǎn)了*/
int get_ring_buff_fullstate(struct ring_buff * p_ring_buff)
{
/*如果寫(xiě)位置減去讀位置等于隊(duì)列長(zhǎng)度,就說(shuō)明這個(gè)環(huán)形隊(duì)列已經(jīng)滿(mǎn)*/
if((p_ring_buff->W - p_ring_buff->R) == LEN)
{
return (1);
}
else
{
return (0);
}
}

/*判斷環(huán)形隊(duì)列為空*/
int get_ring_buff_emptystate(struct ring_buff * p_ring_buff)
{
/*如果寫(xiě)位置和讀的位置相等,就說(shuō)明這個(gè)環(huán)形隊(duì)列為空*/
if(p_ring_buff->W == p_ring_buff->R)
{
return (1);
}
else
{
return (0);
}
}
/*插入數(shù)據(jù)*/
int ring_buff_insert(struct ring_buff * p_ring_buff,int data)
{
if(p_ring_buff == NULL)
{
  printf("p null\n");
  return (-1);
}

if(get_ring_buff_fullstate(p_ring_buff) == 1)
{
printf("buff is full\n");
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\n",data,p_ring_buff->W);
return (0);
}

/*讀取環(huán)形隊(duì)列數(shù)據(jù)*/
int ring_buff_get(struct ring_buff * p_ring_buff)
{
int data = 0;

if(p_ring_buff == NULL)
{
  printf("p null\n");
  return (-1);
}

if(get_ring_buff_emptystate(p_ring_buff) == 1)
{
printf("buff is empty\n");
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;
}

/*銷(xiāo)毀*/
int ring_buff_destory(struct ring_buff * p_ring_buff)
{
if(p_ring_buff == NULL)
{
  printf("p null\n");
  return (-1);
}

free(p_ring_buff);

return (0);
}

int main()
{
int i = 0;

/*定義一個(gè)環(huán)形緩沖區(qū)*/
ring pt_ring_buff = fifo_init();

/*向環(huán)形緩沖區(qū)中寫(xiě)入數(shù)據(jù)*/
for(i = 0;i<10;i++)
{
ring_buff_insert(pt_ring_buff,i);
}

/*從環(huán)形緩沖區(qū)中讀出數(shù)據(jù)*/
for(i = 0;i<10;i++)
{
printf("%d ",ring_buff_get(pt_ring_buff));
}

/*銷(xiāo)毀一個(gè)環(huán)形緩沖區(qū)*/
ring_buff_destory(pt_ring_buff);

return (1);
}

看完上述內(nèi)容,你們掌握C語(yǔ)言中怎么實(shí)現(xiàn)一個(gè)環(huán)形隊(duì)列的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!

本文名稱(chēng):C語(yǔ)言中怎么實(shí)現(xiàn)一個(gè)環(huán)形隊(duì)列
當(dāng)前鏈接:http://bm7419.com/article42/jcichc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供做網(wǎng)站、響應(yīng)式網(wǎng)站定制開(kāi)發(fā)、網(wǎng)站設(shè)計(jì)公司、域名注冊(cè)、電子商務(wù)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁(yè)設(shè)計(jì)