如何在Qt/ c++中有效地重新初始化多维数组

How do I reinitialize a multidimensional array efficiently in Qt/C++?

本文关键字:初始化 数组 有效地 Qt c++      更新时间:2023-10-16

在Qt中,我有一个3-D int-array(例如ID[x][y][z]),我需要在计算期间将其设置为0。

有没有一种不使用循环的有效方法?

我需要重新初始化,因为我正在运行一个带有简单成本函数的特定算法,以获得对以下更详细计算的估计,并且我希望使用相同的数据结构。简单地覆盖数组不是一种选择,因为算法在写入条目之前会读取并检查条目。

迟早会有一个循环,但你可以把它委托给另一个更优化的函数。

同样,如果"3D数组"真的是一些基本类型的数组的数组的数组(如intchar),那么所有的内存都是连续的,所以你可以使用一个函数调用来清除所有的内存。

现在使用哪个函数;在c++中,基本上有两个函数可以使用:旧的C memset函数和c++ std::fill函数。两者都应该工作良好,适当的转换和大小,设置所有的数据为一个特定的值。

实际上它(几乎)总是一个循环。不用担心,没有分支的循环非常高效。

如果你想更容易读,你可以使用memsetstd::fill这样的函数来隐藏循环。

看一下这个问题的答案:使用std::fill填充多维数组的安全方法是什么?

用户@JoachimPileborg和@GeorgSchölly已经在他们的答案中解释了哪些函数可以用来重新初始化数组。但是,我想添加一些示例代码并解释std::fill()memset()之间的区别。

我假设你想用0(重新)初始化你的数组。在本例中,您可以按照以下代码进行操作:

#include <xutility>  // For std::fill().
int main(int argc, char* argv[])
{
    const int x = 2;
    const int y = 3;
    const int z = 5;
    const int arraySize = x * y * z;
    // Initialize array with 0.
    int ID[x][y][z] = {};
    // Use the array...
    // Either reinitialize array with 0 using std::fill()...
    std::fill(&ID[0][0][0], &ID[0][0][0] + arraySize, 0);
    // ...or reinitialize array with 0 using memset().
    memset(&ID[0][0][0], 0, sizeof(ID));
    // Reuse the array...
    return 0;
}

然而,如果你想用另一个值初始化你的数组(例如,1),那么你必须意识到std::fill()memset()之间的一个关键区别:std::fill()函数将数组的每个元素设置为指定的值。相反,memset()函数将数组中的每个字节设置为指定的值。这就是为什么memset()将数组大小作为字节数(sizeof(ID))。

如果用0初始化数组,这个差异不会引起问题。但是,如果您想用非零值初始化数组中的每个元素,则必须使用std::fill(),因为memset()将产生错误的结果。

假设您想将数组的所有元素都设置为1,那么下面这行代码将产生预期的结果:

std::fill(&ID[0][0][0], &ID[0][0][0] + arraySize, 1);

但是,如果您以以下方式使用memset(),那么您将得到不同的结果:

memset(&ID[0][0][0], 1, sizeof(ID));
如上所述,这行代码将每个字节设置为1。因此,数组中的每个整数元素将被设置为16843009,因为它等于十六进制值0x01010101。