本质上是一个数组,但是它又跟普通的数组不太一样,普通的数组只有一个指针,移动下标是index+1的方式;
而环形缓冲区有两个指针:
head指针:表示读取数据的指针;
tail指针:表示写数据的指针。
它是如何实现环形读写的呢?
通过对读写指针的移动进行取模(求余)运算实现的。
对于读指针,如果当前位置有数据可读,那么读取后指针移动,移动方式为:(head+1)%size。
对于写指针,如果当前位置可写入数据,那么写入数据后指针移动,移动方式为:(tail+1)%size。
通过求余的计算方式,每当指针的值达到size-1时,总能通过求余的方式回到0的位置,而后再进行相应的读写操作,指针再继续按照上述方式进行移动。
环形缓冲区主要用于数据读写,相对应的有两个重要的判断条件:
1、缓冲区为空不能读;
2、缓冲区已满不能写。
缓冲区为空的判断条件:读指针等于写指针,即head==tail。
//进行读操作之前需要先判断下这个条件,不满足这个条件才能读
if(head==tail){
...
}
因为写指针指向的位置表示可写入数据的位置,也就是说此时写指针指向的位置是没有数据的,因此当读写指针相同时,说明读指针指向的位置也是没有数据可读的。
缓冲区已满的判断条件:(写指针+1)%缓冲区容量 == 读指针,即(tail+1)%size == head。
//进行写操作之前需要先判断下这个条件,不满足这个条件才能写
if((tail+1)%size==head){
...
}
在head!=tail的情况下,head指针指向的位置是有可读数据存在的;
而当(tail+1)%size==head成立的话,那么tail是可写入数据的位置;
当时如果在此位置写入数据的话,写指针就要移动到head的位置,即形成head==tail为true的结果;
这个条件是表示没有可读数据的条件,但是目前明显是有数据可读的,显然不成立;
所以如果(tail+1)%size==head成立,则不允许继续写入数据了;
此时缓冲区已满(实际上tail指针位置还是空的,但是也不允许写入了,因为一旦写入指针就会变成head==tail为true,与目前的情况矛盾)
网友评论