【发布时间】:2016-10-25 17:55:12
【问题描述】:
我已经为环形缓冲区编写了以下代码。我只想使用没有任何位置指示器的指针。但是我在写作时没有得到预期的结果。尽管发生了写入,但它不会在第一次进入后停止。它继续进一步。读取操作似乎是正确的。
我尝试使用调试器进行调试。但令我惊讶的是,if(head>(myRing+AVAILABLE_SIZE*sizeof(myRing[0]))) 没有在函数 writeToRing() 函数中执行。调试器正在跳过这一步。同样,第一次 head++ 没有在这个函数中执行,而是代码将首先转到 if(head==tail) 然后返回到 head++;找不到原因。
我在 MinGW 中使用 Code::Blocks
#define MAX_SIZE 2
#define AVAILABLE_SIZE (MAX_SIZE-1)
/*
Program to construct and access ring buffer without structure.
This program makes use of pointer. Even without pointer it is possible to manage
*/
int myRing[MAX_SIZE];
int *head=myRing; // Initialize next element than tail
int *tail=myRing;
enum ERROR_LIST
{
SUCCESS=0,
BUFFER_FULL=-1,
BUFFER_EMPTY=-2
};
int writeToRing(int data)
{
head++;
if(head>(myRing+AVAILABLE_SIZE*sizeof(myRing[0])))
{
head=myRing; //wraps over
}
else
{
// Do nothing
}
if(head==tail)
{
head--;
if(head<myRing) // In case head is less than starting address. assign max address
{
head=(myRing+AVAILABLE_SIZE*sizeof(myRing[0]));
}
printf("Buffer full\n");
return(BUFFER_FULL);
}
else
{
*head=data;
}
return(SUCCESS);
}
int readFromBuffer(int* data)
{
if(tail==head)
{
return(BUFFER_EMPTY);
}
else
{
tail++;
if(tail>(myRing+AVAILABLE_SIZE*sizeof(myRing[0])))
{
tail=myRing;
}
*data=*tail;
return(SUCCESS);
}
}
int main()
{
int option;
int data;
while(1)
{
printf("Enter Your option. 1 for writing to buffer, 2 for reading from Buffer\n");
scanf("%d",&option);
if(option==1)
{
printf("Enter the data to be written\n");
scanf("%d",&data);
if(writeToRing(data))
{
printf("Buffer is Full. Remove the contents first\n");
}
}
else if(option==2)
{
if(!readFromBuffer(&data))
{
printf("The data read = %d\n",data);
}
else
{
printf("Buffer is Empty\n");
}
}
else
{
printf("Invalid Option\n");
}
}
return(0);
}
编辑: 用另一种方法更新了代码。在此代码中,不会浪费一个数据字节。我进行了测试,似乎正在工作。但如果有任何其他问题,请告诉我。类型说明符为 %u 的 scanf 有两个警告,需要查看如何修复它。在这种情况下,我基本上想读取字节。如果我去整数读取,没有问题。
#include <stdio.h>
#include <stdint.h>
#define MAX_SIZE 3
uint8_t BUFFER_FULL=0; // Initially buffer full flag is cleared
uint8_t BUFFER_EMPTY=1; // Initially buffer empty flag is set
/*
Program to construct and access ring buffer without pointer.
Also this makes use of full buffer and checks for buffer empty or buffer full condition
before calling write or read functionality,
*/
uint8_t myRing[MAX_SIZE];
uint8_t head=0; // Initialize the head
uint8_t tail=0; // Initialize the tail
uint8_t maxPosition= MAX_SIZE-1;
void writeToRing(uint8_t data)
{
head=head+1;
if(head>maxPosition)
{
head=0;
}
else
{
// Do nothing
}
// Write the data to buffer
myRing[head]=data;
BUFFER_EMPTY=0; // Indicate that buffer is not empty
if(head==tail)
{
printf("Buffer full No further data can be written\n");
BUFFER_FULL=1;
}
}
void readFromRing(uint8_t* data)
{
// Initially buffer is empty (BUFFER_EMPTY=1). At that point, calling portion cannot call this function.
// Later when data is written, writeToRing() function will clear BUFFER_EMPTY flag.
tail++;
if(tail>maxPosition)
{
tail=0;
}
*data=myRing[tail];
// Once reading is done, ensure that BUFFER_FULL flag is cleared.
BUFFER_FULL=0;
if(tail==head)
{
printf("Buffer is now Empty. No further reading possible\n");
BUFFER_EMPTY=1;
}
}
int main()
{
uint8_t option;
uint8_t data;
while(1)
{
printf("Enter Your option. 1 for writing to buffer, 2 for reading from Buffer\n");
scanf("%u",&option);
if(option==1)
{
if(!BUFFER_FULL)
{
printf("Enter the data to be written\n");
scanf("%u",&data);
writeToRing(data);
}
else
{
// Nothing to be done in case buffer is FULL
printf("Buffer should be cleared first\n");
}
}
else if(option==2)
{
if(!BUFFER_EMPTY)
{
uint8_t data;
readFromRing(&data);
printf("The data read = %d\n",data);
}
else
{
printf("Buffer is Empty. Write something before you read\n");
}
}
else
{
printf("Invalid Option\n");
}
}
return(0);
}
【问题讨论】:
标签: c mingw circular-buffer