我刚开始学习C语言。现在我的任务是编写一个简单的环形缓冲区。 我写了一段代码,但它没有用。我无法解决问题,显然,我在推送和弹出功能中指出了错误的参数。它需要使用缓冲区的头部,尾部和大小(我认为问题在于尾部,但是不能正常得到)。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct ringBuffer
{
void *bufferData;
int head;
int tail;
int size;
int numElements;
};
void bufferInitialization(struct ringBuffer *buffer, int size)
{
buffer->size = size;
buffer->head = 0;
buffer->tail = 0;
buffer->numElements = 0;
buffer->bufferData = (void*)malloc(sizeof(int)*size);
}
void bufferFree(struct ringBuffer *buffer)
{
free(buffer->bufferData);
}
int pushBack(struct ringBuffer *buffer, int *data)
{
/* int i;
i = buffer->head + buffer->tail + 1;
if (i >= buffer->size)
{
i = 0;
}
buffer->bufferData[i] = data;*/
memcpy((void*)buffer->head, data, buffer->size);
buffer->head = buffer->head + buffer->size;
if (buffer->head == buffer->tail)
{
buffer->head = (int)buffer->bufferData; //error?
}
buffer->numElements++;
return 0;
}
int popFront(struct ringBuffer *buffer, void *data)
{
//void * bufferData;
/*bufferData = buffer->bufferData[buffer->head];
buffer->head++;
buffer->tail--;
if (buffer->head == buffer->size)
{
buffer->head = 0;
}
//return bufferData;*/
memcpy(data, (void*)buffer->tail, buffer->size); //error?
buffer->tail = buffer->tail + buffer->size;
if ((void*)buffer->tail == buffer->bufferData)
{
buffer->tail = (int)buffer->bufferData; //error?
}
buffer->numElements--;
return 0;
}
int main()
{
struct ringBuffer buffer;
int size = 5;
//*buffer->size = 6;
bufferInitialization(&buffer, size);
char *data[] = { "1" , "2", "3", "4" , "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20" };
for (int i = 0; i < size; i++)
{
printf("Push: data[%d] = %s\n", i, *data[i]);
pushBack(&buffer, (int*)data[i]);
}
printf("\n");
for (int i = 0; i < size; i++)
{
printf("PushBack: queue[%d] = %s\n", i, (ringBuffer*)popFront(&buffer, (void*)data[i])); // !!!
}
printf("\n");
for (int i = 0; i < size; i++)
{
printf("PopFront: data[%d] = %s\n", i, *data[i]);
pushBack(&buffer, (int*)data[i]);
}
printf("\n");
system("pause");
return 0;
}
感谢您提供任何帮助和建议!
答案 0 :(得分:1)
好吧,我决定在缓冲区结构中只使用4个值,看起来效果很好。在代码的末尾有一个dataBuffer检查。
现在我需要编写一个printBuffer函数,只是为了在dataBuffer中显示从HEAD到TAIL的值但是我注意到了一个问题:每次我在缓冲区中写入一个值时,HEAD和TAIL之间的差值总是1(正如我所理解的那样) buffer为空,size = 8且data []中只有6个值,它必须显示为bufferData [0] = 1 ... bufferData [5] = 6,但结果工作不正确。你能解释一下吗?请问如何将printBuffer函数带到可接受的形式?
感谢。这是我的代码(它可以工作,到处检查):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct ringBuffer
{
int *bufferData;
int head;
int tail;
int size;
};
void bufferFree(struct ringBuffer *buffer)
{
free(buffer->bufferData);
}
void bufferInitialization(struct ringBuffer *buffer, int size)
{
buffer->size = size;
buffer->head = 0;
buffer->tail = 0;
buffer->bufferData = (int*)malloc(sizeof(int) * size);
}
void printBuffer(struct ringBuffer *buffer, int i, int size)
{
printf("Values from HEAD to TAIL: ");
if (buffer->head == buffer->tail)
{
printf("Head and tail are equals\n");
}
else
{
printf("bufferData[%d] = %d\n", i, buffer->bufferData);
}
}
int pushBack(struct ringBuffer *buffer, int data)
{
buffer->bufferData[buffer->tail++] = data;
if (buffer->tail == buffer->size)
{
buffer->tail = 0;
}
return 0;
}
int popFront(struct ringBuffer *buffer)
{
if (buffer->head != buffer->tail)
{
buffer->head++;
if (buffer->head == buffer->size)
{
buffer->head = 0;
}
}
return 0;
}
int main(int argc, char* argv[])
{
struct ringBuffer buffer;
int size = 8;
int data[] = { 11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30 }; // 20 values
int dataSize = sizeof(data)/sizeof(data[0]);
/* Test implimention with 1 element in dataBuffer */
bufferInitialization(&buffer, size);
printf("Head : %d - Tail: %d\n", buffer.head, buffer.tail);
pushBack(&buffer, 5);
printf("Head : %d - Tail: %d\n", buffer.head, buffer.tail);
popFront(&buffer);
printf("Head : %d - Tail: %d\n", buffer.head, buffer.tail);
printf("\nnumElements in data = %d : bufferSize = %d\n\n", dataSize, size);
bufferFree(&buffer);
/* Implimention with dada[] */
printf("INITIALIZATION\n");
bufferInitialization(&buffer, size);
printf("Head : %d - Tail: %d\n", buffer.head, buffer.tail);
/* pushBack call */
printf("\nPUSHBACK\n\n");
for (int i = 0; i < dataSize; i++)
{
pushBack(&buffer, data[i]);
printf("Head : %d - Tail : %d :: Data = %d (data[%d]) \n", buffer.head, buffer.tail, data[i], i);
/*for (int k = buffer.head; k<=buffer.tail; k++)
{
// Print methode from head to tail
printBuffer((ringBuffer*)buffer.bufferData, i, size);
}*/
popFront(&buffer);
}
popFront(&buffer);
printf("Head : %d - Tail : %d :: (popFront)\n", buffer.head, buffer.tail);
/* bufferData check */
printf("\nbufferData check:\n");
for (int i = 0; i < size; i++)
{
printf("[%d] = %d ", i, buffer.bufferData[i]);
}
printf("\nHead : %d - Tail : %d\n", buffer.head, buffer.tail);
bufferFree(&buffer);
system("pause");
return 0;
}
答案 1 :(得分:0)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct ringBuffer
{
char *bufferData;
void *bufferEnd;
int head;
int tail;
int size;
int used;
int capacity; // "вместимость"
};
void bufferInitialization(struct ringBuffer *buffer, int capacity, int size)
{
buffer->bufferData = (char*)malloc(capacity * size);
if (buffer->bufferData == 0)
{
buffer->bufferEnd = (char *)buffer->bufferData + capacity * size;
}
buffer->capacity = capacity;
buffer->used = 0;
buffer->size = size;
buffer->head = *buffer->bufferData;
buffer->tail = *buffer->bufferData;
}
void bufferFree(struct ringBuffer *buffer)
{
free(buffer->bufferData);
}
int pushBack(struct ringBuffer *buffer, char *data)
{
if (buffer->used == buffer->capacity) {
printf("Capacity error\n");
buffer->bufferData = 0; //??
}
memcpy((ringBuffer*)buffer->head, data, buffer->size);
buffer->head = buffer->head + buffer->size;
if (buffer->head == (char)buffer->bufferEnd)
{
buffer->head = (char)buffer->bufferData;
}
buffer->used++;
return 0;
}
int popFront(struct ringBuffer *buffer, char *data)
{
if (buffer->used == 0)
{
printf("Buffer is clear\n");
}
memcpy(data, (ringBuffer*)buffer->tail, buffer->size);
buffer->tail = (char)buffer->tail + buffer->size;
if (buffer->tail == (char)buffer->bufferEnd)
{
buffer->tail = (char)buffer->bufferData;
}
buffer->used--;
return 0;
}
int main()
{
struct ringBuffer buffer;
int size = 6;
int capacity = 10;
bufferInitialization(&buffer, capacity, size);
char *data[] = { "1" , "2", "3", "4" , "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20" };
for (int i = 0; i < size; i++)
{
printf("Push: data[%d] = %d\n", i, *data[i]);
pushBack(&buffer, (char*)data[i]);
}
printf("\n");
for (int i = 0; i < size; i++)
{
printf("PushBack: queue[%d] = %s\n", i, (ringBuffer*)popFront(&buffer, (char*)data[i])); // !!!
}
printf("\n");
for (int i = 0; i < size; i++)
{
printf("PopFront: data[%d] = %s : %s\n", i, *data[i]);
pushBack(&buffer, (char*)data[i]);
}
printf("\n");
system("pause");
return 0;
}
答案 2 :(得分:0)
这是一个没有memcpy的示例。因此,您可以在复制时看到缓冲区末端的问题。它没有经过测试,但展示了如何继续。这是一个char
铃声,所以你必须写一个字符。没有检查\0
,因此如果您读写“字符串”,则必须包含它们。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct ringBuffer
{
char *bufferData;
char *head;
char *tail;
char *end;
int size;
int free;
};
void bufferInitialization(struct ringBuffer *buffer, int size)
{
buffer->size = size;
buffer->used = 0;
buffer->head =
buffer->tail =
buffer->bufferData = malloc(size);
buffer->end = buffer->bufferData + size;
}
int pushBack(struct ringBuffer *buffer, char *data, int size)
{
if(size > buffer->size - buffer->used) return -1;
for( ; size>0 && buffer->used < buffer->size; buffer->used++, size--) {
*buffer->head = *data;
buffer->head++;
data++;
if(buffer->head == buffer->end) buffer->head = buffer->bufferData;
}
return 0;
}
int popFront(struct ringBuffer *buffer, char *data, int size)
{
if(size > buffer->used) return -1;
for( ; size>0 && buffer->used > 0; buffer->used--, size--) {
*data = *buffer->tail;
buffer->tail++;
data++;
if(buffer->tail == buffer->end) buffer->tail = buffer->bufferData;
}
return 0;
}