温馨提示:本文翻译自stackoverflow.com,查看原文请点击:c++ - Element-wise shifting from smaller array to a larger array
arduino arduino-c++ c++ embedded

c++ - 从较小的数组到较大的数组的元素明智的转变

发布于 2020-04-13 18:31:22

我在Arduino框架中编写ESP32。对于我的应用程序,我需要创建一个缓冲区,该缓冲区将存储当前和上次访问它的信息。这是我正在尝试做的事情。

//first buffer
char buffer1[4];

//second buffer
char buffer2[8];

void setup {
    //setup
}

//buffer1 values will change with each iteration of loop from external inputs
//buffer2 must store most recent values of buffer1 plus values of buffer1 from when loop last ran

for example:

**loop first iteration**
void loop {
    buffer1[0] = {1};
    buffer1[1] = {2};
    buffer1[2] = {3};
    buffer1[3] = {1};

    saveold(); //this is the function I'm trying to implement to save values to buffer2 in an element-wise way
}
//value of buffer2 should now be: buffer2 = {1,2,3,1,0,0,0,0}

**loop second iteration**
void loop {
    buffer1[0] = {2};
    buffer1[1] = {3};
    buffer1[2] = {4};
    buffer1[3] = {2};

    saveold();
}

//value of buffer2 should now be: buffer2 = {2,3,4,2,1,2,3,1}

从我通过在线搜索所能了解的内容来看,我想创建的“保存”功能应该为这些数组操作实现某种形式的记忆

我尝试将其组合在一起,但是我总是覆盖buffer2的值,而不是以某种方式移入新值,同时保留旧值

这就是我所拥有的:

void saveold() {
  memmove(&buffer2[0], &buffer1[0], (sizeof(buffer1[0]) * 4));
}

据我了解,这会将缓冲区1从索引位置0开始复制到缓冲区2,从索引位置0开始复制4个字节(其中1个字符= 1个字节)。

计算机科学不是我的背景,所以也许我缺少一些基本的解决方案或策略。任何指针将不胜感激。

查看更多

提问者
kevinaguy
被浏览
72
the busybee 2020-02-03 15:28

您可以通过多种选择来实现saveold()

解决方案1

void saveold() {
    // "shift" lower half into upper half, saving recent values (actually it's a copy)
    buffer2[4] = buffer2[0];
    buffer2[5] = buffer2[1];
    buffer2[6] = buffer2[2];
    buffer2[7] = buffer2[3];
    // copy current values
    buffer2[0] = buffer[0];
    buffer2[1] = buffer[1];
    buffer2[2] = buffer[2];
    buffer2[3] = buffer[3];
}

解决方案2

void saveold() {
    // "shift" lower half into upper half, saving recent values (actually it's a copy)
    memcpy(buffer2 + 4, buffer2 + 0, 4 * sizeof buffer2[0]);
    // copy current values
    memcpy(buffer2 + 0, buffer1, 4 * sizeof buffer1[0]);
}

一些注意事项

  • 还有更多的方法可以做到这一点。无论如何,请选择最了解的一种。
  • 确保buffer2是的两倍大小buffer1
  • memcpy()如果源和目标不重叠,则可以安全使用。memmove()检查重叠并做出相应的反应。
  • &buffer1[0]与相同buffer1 + 0随意使用您更好理解的表达方式。
  • sizeof是运算符,而不是函数。因此sizeof buffer[0]计算为的大小buffer[0]用于计算数组维数大小的常见且最常用的表达式是sizeof buffer1 / sizeof buffer1[0]当评估数据类型的大小时才需要括号sizeof (int)

解决方案3

最后的注释直接导致解决方案1的改进:

void saveold() {
    // "shift" lower half into upper half, saving recent values
    size_t size = sizeof buffer2 / sizeof buffer2[0];
    for (int i = 0; i < size / 2; ++i) {
        buffer2[size / 2 + i] = buffer2[i];
    }
    // copy current values
    for (int i = 0; i < size / 2; ++i) {
        buffer2[i] = buffer1[i];
    }
}

将此知识应用到解决方案2的练习留给您。;-)