Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从较小阵列向较大阵列的元素方向移动_C++_Arduino_Embedded_Arduino C++ - Fatal编程技术网

C++ 从较小阵列向较大阵列的元素方向移动

C++ 从较小阵列向较大阵列的元素方向移动,c++,arduino,embedded,arduino-c++,C++,Arduino,Embedded,Arduino C++,我正在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 m

我正在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}
从我通过在线搜索了解到的情况来看,我正在尝试实现的“saveold”功能 应该为这些数组操作实现某种形式的memmove

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

这就是我的全部:

void saveold() {
  memmove(&buffer2[0], &buffer1[0], (sizeof(buffer1[0]) * 4));
}
据我所知,这会将从索引位置0开始的buffer1复制到从索引位置0开始的buffer2,共复制4个字节(其中1个字符=1个字节)


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

您有多个选项可以实现
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];
    }
}
void saveold(){
//将下半部分“移位”到上半部分,保存最近的值
size_t size=sizeof buffer2/sizeof buffer2[0];
对于(int i=0;i

将此知识应用于解决方案2的操作留给您。;-)

正确的方法是使用缓冲区指针,而不是通过硬拷贝备份。使用memcpy进行硬拷贝在速度较慢的传统微控制器(如AVR)上尤其糟糕。不太清楚这台ESP32的MCU是什么,似乎是来自Tensilica的奇怪的一台。不管怎么说,这个答案普遍适用于任何数据超过CPU数据字长的处理器

也许有一些根本性的解决方案或策略是我所缺少的


的确,听起来你要找的是一个环形缓冲区。也就是说,一个大小固定的数组,其中一个指针指向有效数据的开头,另一个指针位于数据的结尾。您移动的是指针,而不是数据。与使用
memcpy

制作简单的硬拷贝相比,这在执行速度和RAM使用方面都要高效得多,因为您实际上没有移动任何东西。您每次只是从
buffer1
复制到
buffer2
中的同一位置。我个人不会费心移动实际数据,而是保留一个标志,告诉您每次调用时开始复制到哪个字节。但如果您真的必须复制,请执行以下操作:
memmove(&buffer2[4],&buffer2[0],(sizeof(buffer2[0])*4));memcpy(&buffer2[0],&buffer1[0],(sizeof(buffer1[0])*4))选择C或C++,而不是两者。最好的答案取决于语言。在微控制器上使用memcpy几乎从来都不是正确的解决方案。在95%的情况下,人们在这样的系统中使用memcpy,他们应该使用指针交换。尽管在这种特定情况下,最好的解决方案似乎是保留一个单环缓冲区-假设没有硬件限制,例如DMA强制执行双缓冲区设计,这在问题中没有任何说明。@Lundin如果您需要性能和足够的RAM,那就对了。另一种方法是
memcpy()
。正如我所写的,还有更多的可能性,这完全取决于需求和环境。我刚刚从他所在的地方找到了OP。OP的代码已经有了多个缓冲区,所以只要做最小的更改,正确的解决方案就是进行指针交换。老实说,解决方案1的简单性非常吸引人。它对我的应用程序也很有效,所以我将坚持使用它。不过,为了便于学习,我还将尝试实现一个环形缓冲区(现在我知道它叫什么了)。这很有教育意义!