【问题标题】:trying to create a circular buffer in C++ using struct尝试使用 struct 在 C++ 中创建循环缓冲区
【发布时间】:2019-05-25 07:46:58
【问题描述】:

我想使用 c++ 中的结构创建一个循环缓冲区。基本实现。我在将元素插入缓冲区时遇到问题。这是我写的代码。

这是我的结构定义:

#define LENGTH_BUFFER 100
typedef struct {
  int buffer[LENGTH_BUFFER];
  int head;
  int tail;
} ringbuffer;


ringbuffer test;

初始化设置指针为0:

void RingBuffer_Init(ringbuffer temp)
{
  temp.head = 0;
  temp.tail = 0;
}

数据推送功能:

void RingBuffer_Push(int data,ringbuffer temp)
{
  temp.buffer[temp.head] = data;
  temp.head++;
}

这里是我调用函数来初始化和推送数据的地方

void main()
{
  RingBuffer_Init(test);
  RingBuffer_Push(25,test);

  cout << test.buffer[0]<<endl;
}

我似乎无法将数据推送到我的缓冲区。请帮帮我。它返回全零。

【问题讨论】:

  • 欢迎来到 Stack Overflow!请使用tour 并阅读How to Ask,作为新用户的指南。关于您的代码,LENGTH_BUFFER 是未定义的,typedef struct ... 在 C++ 中是不必要的,并且整个代码的格式并不是一致的,这使得阅读和理解变得困难。此外,“我似乎不能”是一种解释,但您缺乏引导您做出这种解释的实际观察结果。
  • RingBuffer_Init 和 RingBuffer_Push 都按值获取环形缓冲区,这意味着 temp 是您正在修改的副本。而是通过引用传递它们。
  • void RingBuffer_Push(int data,ringbuffer temp) 必须是 void RingBuffer_Push(int data,ringbuffer &amp; temp) 以避免获取环形缓冲区的副本
  • 如果您更改副本,则 main 中的原件不变,因此 main 中的环仍然是空的
  • 行为与内置类型相同。 void f(int i) { i++ ; /* here i values 2 */ } void g() { int i = 1 ; f(i); /* here i values 1, not 2 */ }

标签: c++ data-structures struct


【解决方案1】:

假设 head 是你放置新值的索引,当你推送一个值时,temp.head++;必须替换为temp.head = (temp.head + 1) % BUFFER_LENGTH;来管理缓冲区的长度。当缓冲区已满时,您还必须移动 tail

我不明白为什么你推 1 个值然后写 5 个值

你说你是用 C++ 写的,那你为什么用 C 写呢?为什么你在 ringbuffer 上没有构造函数和 push/pop/top 操作?

{编辑添加}

正如您要求在 c++ 中做的一个非常简单的方法

#include <iostream>
using namespace std;

#define LENGTH_BUFFER 4

// in c++ we use a struct when all members are public (by default all is public in a struct),
// but this is dangerous because all can be modified from outside without any protection,
// so I prefer to use a class with public/private parts

class RingBuffer {
  public:
    // The constructor, it replaces RingBuffer_Init,
    // The big advantage is you cannot miss to call the constructor
    RingBuffer();

    // it is not needed to have a destructor, the implicit destructor is ok

    // because it is an operation you do not have to give the ringbuffer in parameter
    void push(int data);

    // I had the print operation, it print following the order of insertion
    // to print doesn't change the instance, so I can say the operaiotn is 'const'
    void print() const;

  private:
    int buffer[LENGTH_BUFFER];
    int head; // index of the future value
    int tail; // index of the older inserted value, except if empty / head == index
};

// The buffer is initialized empty, head == tail
// I can initialize the indexes by any other valid
// value, this is not relevant
RingBuffer::RingBuffer() : head(0), tail(0) {
}

// push a new value, 
void RingBuffer::push(int data)
{
  buffer[head] = data;
  head = (head + 1) % LENGTH_BUFFER;

  if (head == tail)
    tail = (tail + 1) % LENGTH_BUFFER;
}

// print the content and indexes
void RingBuffer::print() const {
  for (int p = tail; p != head; p = (p + 1)  % LENGTH_BUFFER)
    cout << buffer[p] << ' ';
  cout << " (head=" << head << ", tail = " << tail << ')'  << endl;
}

int main()
{
  RingBuffer test;

  test.print();

  test.push(1);
  test.print();

  test.push(2);
  test.print();

  test.push(3);
  test.print();

  test.push(4);
  test.print();

  test.push(5);
  test.push(6);
  test.print();

  return 0;
}

我减小了缓冲区的大小以使用少量值进行旋转。

执行产生:

 (head=0, tail = 0)
1  (head=1, tail = 0)
1 2  (head=2, tail = 0)
1 2 3  (head=3, tail = 0)
2 3 4  (head=0, tail = 1)
4 5 6  (head=2, tail = 3)

正如您在该实现中看到的那样,丢失了一个条目,它的大小为 4,但只管理 3 个值。我让你可以改变它,添加 top()、back()、pop() 等

【讨论】:

  • 基本上我只想检查是否正在推送值。我知道它稍后会溢出,但为了实现的目的,我推了 1 个值来检查它是否被插入。
  • 我已经修改了代码。请查看并告诉我。谢谢
  • 你只改变了cout &lt;&lt; test.buffer[0]&lt;&lt;endl;no ?
  • 再一次,你想用C还是C++写?
  • 对您之前的评论也是如此,您说将头部和尾部初始化为 0,所以我将功能分开以将其清除。我想用 c++ 编程。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多