私はリングバッファのコードを以下に書いています。私は位置指示器なしでポインタだけを使いたいと思っていました。しかし、私は執筆中に期待される結果を得ていません。書き込みは行われますが、1回目の入力後に停止しません。それはさらに続く。読み取り操作が正しいようです。 デバッガを使ってデバッグしようとしました。しかし、驚いたことに、if(head>(myRing+AVAILABLE_SIZE*sizeof(myRing[0])))
はwriteToRing()関数で実行されていません。デバッガはこの手順をスキップします。また、最初の++ ++はこの関数で実行されません。代わりに、コードは最初にif(head == tail)に行き、その後++に戻ります。理由を見つけることができません。 私は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);
}
編集でコード::ブロックを使用しています: は別のアプローチでコードを更新しました。このコードでは、1データバイトが無駄にならない。私はテストして働いているようだ。しかし、他の問題がある場合は、私に知らせてください。タイプ指定子%uのscanfには2つの警告があり、修正方法を確認する必要があります。私は基本的にこの場合バイトを読みたいと思う。私が整数読み取りのために行くなら、問題はありません。
#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