我已經寫下了環形緩衝區的代碼。我只想使用沒有任何位置指示器的指針。但是我在寫作時沒有得到預期的結果。雖然寫入發生,但它不會在第一次進入後停止。它繼續下去。閱讀操作似乎是正確的。 我試圖使用調試器進行調試。但令我驚訝的是,if(head>(myRing+AVAILABLE_SIZE*sizeof(myRing[0])))
沒有在函數writeToRing()函數中執行。調試器正在跳過這一步。也是第一次在這個函數中頭++沒有被執行,代碼將首先轉到if(head == tail)然後回到頭++;無法找到原因。 我使用的代碼:: Blocks的使用MinGW使用直接指針操作實現環形緩衝區的問題
#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);
}
事實上,我最初嘗試不乘以sizeof(int)。這讓我感到困擾,然後爲了測試目的而改變了,忘記了刪除。不知道爲什麼調試器跳過了我所指出的步驟。不過今天我按照你的建議做了,它正在工作。一定在某個地方犯了一些愚蠢的錯誤。 – Rajesh