3

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

int array1[20]; 

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

写作效果很好。我用

writeIndex = (writeIndex + 1) %20;

来写。这很好地将数组索引 0 翻转到 19。

为了阅读我正在使用

readIndex = (readIndex -1)%20;

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

4

3 回答 3

6

你的代码

readIndex = (readIndex - 1) % 20;

不起作用,因为当readIndex以 0 开头时,(readIndex - 1) % 20将评估为 -1,然后您的数组访问将超出范围。

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

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

或者干脆

readIndex = (readIndex + 19) % 20;

所以当readIndex从 0 开始时,你可以回绕到 19。

于 2013-10-02T21:26:07.300 回答
1

李玉修给出了实际的答案,这里有一些背景信息。

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

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

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

于 2013-10-02T21:30:18.897 回答
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);
        }
    }
}
于 2013-10-03T08:16:33.597 回答