在Qt中,我有一个3-D int数组(比如ID[x][y][z]
),我需要在计算过程中将其设置为0。
有没有一种有效的方法可以在不使用循环的情况下完成它?
我需要重新初始化,因为我正在运行一个具有简单成本函数的特定算法来估算以下更详细的计算,我想使用相同的数据结构。简单地覆盖数组不是一种选择,因为算法在写入之前会读取和检查条目。
答案 0 :(得分:3)
迟早会有一个循环,但你可以将它委托给另一个更优化的功能。
另外,如果" 3D阵列"实际上是一些基本类型的数组数组(如int
或char
),然后所有内存都是连续的,因此您可以使用单个函数调用来清除 all 一次通话中的记忆。
现在使用哪个功能;在C ++中,基本上可以使用两个函数:旧的C memset
函数和C ++ std::fill
函数。两者都应该正常工作,具有适当的强制转换和大小,以将所有数据设置为特定值。
答案 1 :(得分:0)
在引擎盖下它(几乎)总是一个循环。别担心,没有分支的循环非常有效。
如果您想要更具可读性,可以使用隐藏循环的memset
或std::fill
等函数。
查看此问题的答案:What's the safe way to fill multidimensional array using std::fill?
答案 2 :(得分:0)
用户@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()
之间的重要区别:函数{{1将数组的每个元素设置为指定的值。相反,函数std::fill()
将数组的每个字节设置为指定值。这就是memset()
将数组大小作为字节数(memset()
)。
如果使用0初始化数组,则此差异不会导致问题。
但是,如果要使用非零值初始化数组的每个元素,则必须使用sizeof(ID)
,因为std::fill()
将产生错误的结果。
假设您要将数组的所有元素设置为1,那么以下代码行将产生预期结果:
memset()
但是,如果您按以下方式使用std::fill(&ID[0][0][0], &ID[0][0][0] + arraySize, 1);
,则会得到不同的结果:
memset()
如上所述,这行代码将每个字节设置为1.因此,数组的每个整数元素将设置为16843009,因为这等于十六进制值0x01010101。