• <noframes id="6fok0"><bdo id="6fok0"><listing id="6fok0"></listing></bdo>
    <ruby id="6fok0"></ruby>

    <progress id="6fok0"></progress>
  • <progress id="6fok0"></progress>
    <ruby id="6fok0"><table id="6fok0"></table></ruby>
  • <progress id="6fok0"><u id="6fok0"><form id="6fok0"></form></u></progress>

    24小時(shí)聯(lián)系電話(huà):18217114652、13661815404

    中文

    您當前的位置:
    首頁(yè)>
    電子資訊>
    技術(shù)專(zhuān)題>
    環(huán)形緩沖區C語(yǔ)言實(shí)現

    技術(shù)專(zhuān)題

    環(huán)形緩沖區C語(yǔ)言實(shí)現



    一、環(huán)形緩沖區的特性
    1、先進(jìn)新出
    2、當緩沖區被使用完,且又有新的數據需要存儲時(shí),丟掉歷史最久的數據,保存較新數據
    現實(shí)中的存儲介質(zhì)都是線(xiàn)性的,因此我們需要做一下處理,才能在功能上實(shí)現環(huán)形緩沖區


    算法說(shuō)明:
    1、pHead和pTail分別是連續存儲介質(zhì)的首地址和尾地址
    2、pTail - pHead 的值是環(huán)形緩沖區的總長(cháng)度
    3、pValid 是使用區域的起始指針,取數據時(shí)的起點(diǎn),當取數據時(shí)pValid要發(fā)生偏移
    4、pValidTail 是使用區域的的結尾指針,存數據時(shí)的起點(diǎn),當存數據時(shí),pValidTail要發(fā)生偏移
    5、現有長(cháng)度為addLen字節要存入,當pValidTail + addLen > pTail 時(shí)(超出了緩沖區,這時(shí)就要繞到開(kāi)頭pHead)
    int len1 = pTail - pValidTail;
    int len2 = addLen - len1;
    pValidTail = pHead + len2;//新的使用區的尾指針
    6、判斷總長(cháng)度是否變更,即是否有數據覆蓋pValid所指向的區域,如果有,要偏移pValid

    下面是已驗證的代碼

    ringBuffer.h

    #ifndef RINGBUFFER_H_
    #define RINGBUFFER_H_
    typedef unsigned char u8;
    typedef unsigned int u32;

    void initRingbuffer(void);
    int wirteRingbuffer(u8* buffer,u32 len);
    int readRingbuffer(u8* buffer,u32 len);
    u32 getRingbufferValidLen(void);
    void releaseRingbuffer(void);

    #endif /* RINGBUFFER_H_ */



    ringBuffer.c:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>
    #include "ringBuffer.h"
    #define BUFFER_SIZE  16   //緩沖區的長(cháng)度,可以修改

    static u32 validLen;//已使用的數據長(cháng)度
    static u8* pHead = NULL;//環(huán)形存儲區的首地址
    static u8* pTail = NULL;//環(huán)形存儲區的結尾地址
    static u8* pValid = NULL;//已使用的緩沖區的首地址
    static u8* pValidTail = NULL;//已使用的緩沖區的尾地址

    /*
     * 初始化環(huán)形緩沖區
     * 環(huán)形緩沖區這里可以是malloc申請的內存,也可以是Flash存儲介質(zhì)
     * */
    void initRingbuffer(void)
    {
    if(pHead == NULL)
    {
    pHead = (u8*) malloc(BUFFER_SIZE);
    }
    pValid = pValidTail = pHead;
    pTail = pHead + BUFFER_SIZE;
    validLen = 0;
    }

    /*
     * function:向緩沖區中寫(xiě)入數據
     * param:@buffer 寫(xiě)入的數據指針
     * @addLen 寫(xiě)入的數據長(cháng)度
     * return:-1:寫(xiě)入長(cháng)度過(guò)大
     *   -2:緩沖區沒(méi)有初始化
     * */
    int wirteRingbuffer(u8* buffer,u32 addLen)
    {
    if(addLen > BUFFER_SIZE) return -2;
    if(pHead==NULL) return -1;
    assert(buffer);

    //將要存入的數據copy到pValidTail處
    if(pValidTail + addLen > pTail)//需要分成兩段copy
    {
    int len1 = pTail - pValidTail;
    int len2 = addLen - len1;
    memcpy( pValidTail, buffer, len1);
    memcpy( pHead, buffer + len1, len2);
    pValidTail = pHead + len2;//新的有效數據區結尾指針
    }else
    {
    memcpy( pValidTail, buffer, addLen);
    pValidTail += addLen;//新的有效數據區結尾指針
    }

    //需重新計算已使用區的起始位置
    if(validLen + addLen > BUFFER_SIZE)
    {
    int moveLen = validLen + addLen - BUFFER_SIZE;//有效指針將要移動(dòng)的長(cháng)度
    if(pValid + moveLen > pTail)//需要分成兩段計算
    {
    int len1 = pTail - pValid;
    int len2 = moveLen - len1;
    pValid = pHead + len2;
    }else
    {
    pValid = pValid + moveLen;
    }
    validLen = BUFFER_SIZE;
    }else
    {
    validLen += addLen;
    }

    return 0;
    }

    /*
     * function:從緩沖區內取出數據
     * param   :@buffer:接受讀取數據的buffer
     *     @len:將要讀取的數據的長(cháng)度
     * return  :-1:沒(méi)有初始化
     *     >0:實(shí)際讀取的長(cháng)度
     * */
    int readRingbuffer(u8* buffer,u32 len)
    {
    if(pHead==NULL) return -1;

    assert(buffer);

    if(validLen ==0) return 0;

    if( len > validLen) len = validLen;

    if(pValid + len > pTail)//需要分成兩段copy
    {
    int len1 = pTail - pValid;
    int len2 = len - len1;
    memcpy( buffer, pValid, len1);//第一段
    memcpy( buffer+len1, pHead, len2);//第二段,繞到整個(gè)存儲區的開(kāi)頭
    pValid = pHead + len2;//更新已使用緩沖區的起始
    }else
    {
    memcpy( buffer, pValid, len);
    pValid = pValid +len;//更新已使用緩沖區的起始
    }
    validLen -= len;//更新已使用緩沖區的長(cháng)度

    return len;
    }

    /*
     * function:獲取已使用緩沖區的長(cháng)度
     * return  :已使用的buffer長(cháng)度
     * */
    u32 getRingbufferValidLen(void)
    {
    return validLen;
    }

    /*
     * function:釋放環(huán)形緩沖區
     * */
    void releaseRingbuffer(void)
    {
    if(pHead!=NULL) free(pHead);
    pHead = NULL;
    }



    測試main函數:

    #include <stdio.h>
    #include <stdlib.h>
    #include "ringBuffer.h"
    // 主函數
    int main()
    {
    char c;
    int readLen;
    u8 readBuffer[10];
    //setvbuf(stdout,NULL,_IONBF,0); //pinrtf、putchar不能立馬輸出,打開(kāi)此注釋
    initRingbuffer();

    printf("Please enter a line [blank line to terminate]> ");
    do{
    c=getchar();
    putchar(c);
    switch(c)
    {
    case 'Q':
    goto exit;
    break;
    case 'R':
    readLen = readRingbuffer(readBuffer,10);
    printf("readRingbuffer len:%d\n",readLen);
    if(readLen > 0){
    printf("readRingbuffer:");
    for(int i=0;i<readLen;i++){
    printf("%c ",(char)readBuffer[i]);
    }
    printf("\n");
    }
    break;
    default :
    if(c!='\n') wirteRingbuffer((u8*)&c,1);
    break;
    }
    }while (1);

    exit:
    releaseRingbuffer();
    printf("exit.\n");
        return 0;
    }


    測試文件下載地址:

    ringBuffer.h

    ringBuffer.c

    main.c



    
    
    
    
    
    
    本文原創(chuàng  )初次發(fā)表在:https://blog.csdn.net/maowentao0416/article/details/81984269


    請輸入搜索關(guān)鍵字

    確定
    色鲁99热99re超碰精品_91精品一区二区三区无码吞精_亚洲国产欧洲综合997久久_一级a性色生活片久久无
  • <noframes id="6fok0"><bdo id="6fok0"><listing id="6fok0"></listing></bdo>
    <ruby id="6fok0"></ruby>

    <progress id="6fok0"></progress>
  • <progress id="6fok0"></progress>
    <ruby id="6fok0"><table id="6fok0"></table></ruby>
  • <progress id="6fok0"><u id="6fok0"><form id="6fok0"></form></u></progress>