我有以下数组,我打算将它用作循环缓冲区。
int array1[20];
数组由一个线程写入并由另一个线程读取。在阅读时我需要读取该数组中写入的最后3个值。
写作很好。我用
writeIndex = (writeIndex + 1) %20;
写。这将很好地滚动数组索引0到19。
阅读我正在使用
readIndex = (readIndex -1)%20;
但是当我尝试从索引0转到19时它不起作用。
答案 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);
}
}
}