反转遍历C中的循环缓冲区

时间:2013-10-02 18:37:44

标签: c linux

我有以下数组,我打算将它用作循环缓冲区。

int array1[20]; 

数组由一个线程写入并由另一个线程读取。在阅读时我需要读取该数组中写入的最后3个值。

写作很好。我用

writeIndex = (writeIndex + 1) %20;

写。这将很好地滚动数组索引0到19。

阅读我正在使用

readIndex = (readIndex -1)%20;

但是当我尝试从索引0转到19时它不起作用。

3 个答案:

答案 0 :(得分:4)

您的代码

readIndex = (readIndex - 1) % 20;

无效,因为当readIndex以0开头时,(readIndex - 1) % 20将调整为-1,然后您的数组访问权限将超出范围。

在这种情况下,您不想处理负数。为了避免它发生,您只需在值中添加20:

readIndex = (readIndex - 1 + 20) % 20;

或只是

readIndex = (readIndex + 19) % 20;

因此,当readIndex以0开头时,您可以向后回转到19。

答案 1 :(得分:1)

李玉秀给出了实际的答案,这里有一些背景资料。

问题是在C中定义除法/模数的方式:除法向零舍入,模数由

定义
a%b == a - (a/b)*b

由于除法舍入为零,-1/20为零。因此,-1%20 == -1 - 0*20会产生-1,这不是数组的有效索引。

答案 2 :(得分:0)

好的,不用线程,这是一个测试程序,可以做你想要的。但是你可能想要添加一些东西以确保你至少有3个读数(我没有打扰它)。但重要的计算是采用当前位置(bufferPos),并找到3(N)之前的值。

哦,我评论锁定和解锁的地方,把你的线程锁定......

#include <stdio.h>
#include <stdlib.h>
#define BUFSIZE (20)
int bufferPos = 0;
int Databuffer[BUFSIZE] = {0};
int BufferWrite(int x)
{
    //lock
    Databuffer[bufferPos] = x;
    bufferPos = (bufferPos+1)%BUFSIZE;
    printf("write[%d] %d\n", bufferPos, Databuffer[bufferPos]);
    //unlock
}
int BufferRead(int count)
{
    int rdx;
    int position;
    //lock
    for( rdx=0; rdx<count; ++rdx )
    {
        position = ((bufferPos-1)-rdx);
        if( position<0 ) position = position+BUFSIZE;
        printf("read[%d:%d] %d\n", rdx, position, Databuffer[position]);
    }
    //unlock
}
int main(int argc, char* argv[])
{
    int ndx; int val;
    char line[999];
    for( ndx=0; ndx<100; ++ndx )
    {
        fgets(line,sizeof(line),stdin);
        BufferWrite(atoi(line));
        if( ndx%7 == 0 )  //read a few, occasionally
        {
            BufferRead(3);
        }
    }
}