ring / circular Buffer - 头部和尾部之间的缓冲区实现和打印值

时间:2017-03-26 04:38:38

标签: c

我是编程的初学者,我在使用循环缓冲区时遇到了一些困难。我为我的环形缓冲区写了函数push和pop,它是如何工作的,它似乎有效。但是当我使用pushBack通过每个元素实现dataBuffer并且在循环“for”中相同时,我得到不同的head值。在我的例子中可以看到(我只能在结构中使用4个值+第5个用于计算头部和尾部之间的元素数量):

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    struct ringBuffer
    {
        int *bufferData;
        int head;
        int tail;
        int size;
        int num;
    };

    void bufferFree(struct ringBuffer *buffer)
    {
        free(buffer->bufferData);
    }

    void bufferInitialization(struct ringBuffer *buffer, int size)
    {
        buffer->size = size;
        buffer->head = 0;
        buffer->tail = 0;
        buffer->bufferData = (int*)malloc(sizeof(int) * size);
    }

    int pushBack(struct ringBuffer *buffer, int data)
    {
        buffer->bufferData[buffer->tail++] = data;
        if (buffer->tail == buffer->size)
        {
            buffer->tail = 0;
        }
        return 0;
    }

    int popFront(struct ringBuffer *buffer)
    {
        if (buffer->head != buffer->tail)
        {
            buffer->head++;
            if (buffer->head == buffer->size)
            {
                buffer->head = 0;
            }
        }
        return 0;
    }

    int bufferSize(struct ringBuffer *buffer)
    {
        //int numElements;
        //numElements = (buffer->size + buffer->head + buffer->tail) % buffer->size; // 8 + 0 + 6 % 8 = 6; 
        if (buffer->head >= buffer->tail)
        {
            return (buffer->head - buffer->tail);
        }
        else
        {
            return ((buffer->size - buffer->tail) + buffer->head);
        }

        /*if (buffer->head = !buffer->tail)
        {
        for (buffer->head = 0; buffer->head < buffer->tail; buffer->head++)
        {
        printf("head[%d] and tail[%d] --> bufferData = %d", buffer->head, buffer->tail, buffer->bufferData);
        }
        }*/
        return 0;
    }

    int printBuffer(struct ringBuffer *buffer)
    {
        int size = bufferSize((ringBuffer*)buffer->size);
        int i = buffer->head;
        while (buffer->size >= 0) 
        {
            if (!buffer->bufferData)
            {
                printf("Buffer is empty\n");
                return -1;
            }
            else if (i == buffer->size)
            {

        i = 0;
            }
            printf("    \n");
            buffer->size--;
        }
        /*printf("Values from HEAD to TAIL: ");
        if (buffer->head == buffer->tail)
        {
            printf("Head and tail are equals, not possible to show data\n");
        }
        else
        {
            printf("bufferData[%d] = %d\n", buffer->bufferData);
        }*/
    }

    int main(int argc, char* argv[])
    {
        struct ringBuffer buffer;
        int size = 8;
        int data[] = { 11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30 }; // 20 values
        int dataSize = sizeof(data) / sizeof(data[0]);
        bufferInitialization(&buffer, size);

        printf("1st implementation\n");
        pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
        pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
        pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
        pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
        pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
        pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
        pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
        pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
        //printf("Current num elements = \n", bufferSize((ringBuffer*)buffer.num));

        printf("2nd implementation\n");
        pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
        pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
        pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
        pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
        pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
        pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
        pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
        pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
        bufferFree(&buffer);

        printf("\nInisialization\n");
        bufferInitialization(&buffer, size);
        printf("head = %d, tail = %d - then implementation\n", buffer.head, buffer.tail);
        for (int i = 0; i < dataSize; i++)
        {
            pushBack(&buffer, data[i]);
            printf("head = %d, tail = %d, dataBuffer = %d\n", buffer.head, buffer.tail, data[i]);
            popFront(&buffer);
        }
        printf("\nbufferData check:\n");
        for (int i = 0; i < size; i++)
        {
            printf("[%d] = %d  ", i, buffer.bufferData[i]);
        }
        printf("\nhead = %d, tail = %d\n", buffer.head, buffer.tail);

        bufferFree(&buffer);
        system("pause");
        return 0;
    }

我还必须编写一个显示“head”和“tail”之间元素数量的函数。对于for循环,head和tail之间总是有1个值,在第一个实现head中总是= 0(当实现所有缓冲区时,head = tail)。这里的名称是bufferSize。我必须打印出来。

如何解决头尾问题以及如何编写正确的printBuffer函数?

由于

2 个答案:

答案 0 :(得分:0)

这显然正在发生,因为您的第一个和第二个实现并没有使用您在popFront(...)周期中使用的for函数。 popFront(...)正在向前迈进,显而易见的是,如果你在同一个循环中推送和弹出数据,那么你的缓冲区中永远不会有超过1条记录。

答案 1 :(得分:0)

好吧,似乎我没有完全理解并确定它应该如何运作。由于尾值,我很困惑(第二次实现)。

现在我改变了循环实现的部分,并将其分为3部分:dataSize = 20,因此第1部分从5到5,第2部分从5到13,第3部分从13到缓冲数据作为回报)。

抱歉这些愚蠢的问题,但我真的想学习和理解。

这是我更正后的代码和编译结果。 https://ibb.co/e6jnGF

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct ringBuffer
{
    int *bufferData;
    int head;
    int tail;
    int size;
};

void bufferFree(struct ringBuffer *buffer)
{
    free(buffer->bufferData);
}

void bufferInitialization(struct ringBuffer *buffer, int size)
{
    buffer->size = size;
    buffer->head = 0;
    buffer->tail = 0;
    buffer->bufferData = (int*)malloc(sizeof(int) * size);
}

int pushBack(struct ringBuffer *buffer, int data)
{
    buffer->bufferData[buffer->tail++] = data;
    if (buffer->tail == buffer->size)
    {
        buffer->tail = 0;
    }
    return 0;
}

int popFront(struct ringBuffer *buffer)
{
    if (buffer->head != buffer->tail)
    {
        buffer->head++;
        if (buffer->head == buffer->size)
        {
            buffer->head = 0;
        }
    }
    return 0;
}

int bufferSize(struct ringBuffer *buffer)
{
    if (buffer->head >= buffer->tail)
    {
        return (buffer->head - buffer->tail);
    }
    else
    {
        return buffer->size - ((buffer->size - buffer->tail) + buffer->head);
    }
    for (buffer->head = 0; buffer->head < buffer->tail; buffer->head++)
    {
        printf("head[%d] and tail[%d] --> bufferData = %d", buffer->head, buffer->tail, buffer->bufferData);
    }
    return 0;
}

int printBuffer(struct ringBuffer *buffer)
{
    for (int i = buffer->head; i < buffer->tail; i++)
    {
        if (buffer->head == buffer->tail)
        {
            printf("Head and tail are equals, not possible to show data\n");
        }
        else
        {
            printf("bufferData = %d\n", buffer->bufferData);
        }
    }
    return 0;
}

int main(int argc, char* argv[])
{
    struct ringBuffer buffer;
    int size = 8;
    int data[] = { 11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30 }; // 20 values
    int dataSize = sizeof(data) / sizeof(data[0]);

    bufferInitialization(&buffer, size);
    printf("1st implementation\n");
    pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
    pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
    pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
    pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
    pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail); popFront(&buffer);
    printf("bufferSize = %d\n", bufferSize(&buffer));
    pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
    pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
    pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
    printf("bufferSize = %d\n", bufferSize(&buffer));

    printf("2nd implementation\n");
    pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
    pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
    pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
    pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
    pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
    pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
    pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
    pushBack(&buffer, 10);  printf("head = %d, tail = %d\n", buffer.head, buffer.tail);
    printf("bufferSize = %d\n", bufferSize(&buffer));
    bufferFree(&buffer);

    printf("\nInisialization\n");
    bufferInitialization(&buffer, size);
    printf("head = %d, tail = %d - then implementation\n", buffer.head, buffer.tail);

    for (int i = 0; i < 5; i++)
    {
        pushBack(&buffer, data[i]);
        printf("head = %d, tail = %d, dataBuffer = %d\n", buffer.head, buffer.tail, data[i]);
    }
    printf("bufferSize = %d\n", bufferSize(&buffer));
    popFront(&buffer);
    printBuffer(&buffer);
    printBuffer((ringBuffer*)buffer.bufferData);

    for (int i = 5; i < 13; i++)
    {
        pushBack(&buffer, data[i]);
        printf("head = %d, tail = %d, dataBuffer = %d\n", buffer.head, buffer.tail, data[i]);
    }
    printf("bufferSize = %d\n", bufferSize(&buffer));
    popFront(&buffer);
    printBuffer(&buffer);
    printBuffer((ringBuffer*)buffer.bufferData);

    for (int i = 13; i < dataSize; i++)
    {
        pushBack(&buffer, data[i]);
        printf("head = %d, tail = %d, dataBuffer = %d\n", buffer.head, buffer.tail, data[i]);
    }
    printf("bufferSize = %d\n", bufferSize(&buffer));
    popFront(&buffer);
    printBuffer(&buffer);
    printBuffer((ringBuffer*)buffer.bufferData);



    /* bufferData check */
    printf("\nbufferData check:\n");
    for (int i = 0; i < size; i++)
    {
        printf("[%d] = %d  ", i, buffer.bufferData[i]);
    }
    printf("\nhead = %d, tail = %d\n", buffer.head, buffer.tail);
    bufferFree(&buffer);
    system("pause");
    return 0;
}