将数组的所有元素设置为某个值的最佳方法是什么?

3

我有一个整数数组,每次调用函数时,我想将数组中的所有值都设置为“x”。

我查看了memset,但我认为它只适用于字节数组。

我可以使用显而易见的for循环,但我猜测可能有一个标准库函数能更好地解决这个问题。有人知道吗?


循环是最好的选择。 - cnicutar
1
memset 可能在内部只是一个循环,所以你的循环也同样好。 - Carl Norum
2
@CarlNorum 一个非常花哨的循环 - Jesus Ramos
如果'x'是一个字符,你可以使用memset(array,'x',sizeof(array)) - Rapptz
@JesusRamos,glibc的memset非常简单明了。它有一些对齐和循环展开的处理,但我不知道它是否“非常花哨”。 - Carl Norum
显示剩余2条评论
4个回答

2

如果你使用的是x86系统,可以使用一些汇编代码来实现。例如,在gcc中:

    __asm__(
            "rep stosb"
            : "=a"('x'), "=c"(count), "=D"(array)
           );

应该可以解决问题。 rep stosb指令将AL中的值分配给由ES:EDI指向的连续内存位置。这些位置的数量由ECX指定。
顺便说一下,在最近的处理器中,英特尔公司已经做出了许多努力来提高MOVSBSTOSB的性能,因此这是一个不错的选择。

不要 添加汇编黑客!你所写的只是 memset(3),而编译器(至少GCC)将为 memset 自行执行此操作(如果您不相信,请检查生成的汇编代码)。结果:一个更难理解、不可移植的程序,没有任何收益(可能比编译器做得更糟糕)。 - vonbrand
@vonbrand:你可能是对的。就像人们所说的那样,当你手上只有一把锤子时,每个问题都看起来像个钉子。我比熟悉x86汇编语言更熟悉C语言,当我试图想起memset的时候,我记不起来了,但我可以记得STOSB - Nathan Fellman
感谢提供的信息。在我的情况下,我正在编写需要可移植到多个处理器的代码,所以不能使用这个,但是学习一些新的x86汇编仍然是很好的。谢谢! - Brandon Yates
“=a”('x')应该在输入部分中(非lvalue也不能是输出)。编写“+c”和“+D”更安全,以便编译器不能在进入“asm”语句时更改绑定变量的值。 - xiver77

2

只需要简单的循环即可。如果您知道值为零,则可以使用memset将其设置为零(对于其他您了解位表示的值也是如此)。由于标准库无法了解特定用户类型,因此不会有标准库解决方案。


将memset设置为零有点适得其反,因为int myArray [80] = {0}会将所有数组元素初始化为零。 - Rapptz
2
@Rapptz:仅在定义时。后续填充需要使用memset。 - sheu

1
除了memset和循环(它们都是O(n)时间复杂度),实际上可以在O(1)时间内完成,但代价是三倍的内存使用量,并且后续查找更加昂贵。 本文描述了如何实现这一点。
思路是维护一个额外的栈(逻辑上,由数组+指向顶部的指针实现)和数组,额外的数组将指示何时首次初始化(从0到n的数字),而堆栈将指示哪些元素已经被修改。
当您访问array[i]时,如果stack[additionalArray[i]] == i && i < top,则数组的值为array[i]。 否则-它是“初始化”值。
在执行array[i] = x时,如果尚未初始化(如前所述),则应设置additionalArray[i] = stack[top]并增加top
这导致O(1)的初始化,但需要额外的内存,并且每次访问更加昂贵。

0

以下逻辑将对您有所帮助。

...
int a[100] = {0};
int b = 5;
memset_ex(a, 100, &b, sizeof(int));
...

memset_ex(void *buf, int buf_size, void *value, int size_of_type)
{
    int i = 0;

    for(i = 0; i <= (buf_size - size_of_type); i +=size_of_type)
    {
        memcpy((buf + i), value, size_of_type);
    }
}

这种方法比 for(i=0;i<N;i++) a[i]=5; 好在哪里?我能理解一种叫做“重叠复制”的技术,例如 a[0]=b; memcpy(a+1,a,sizeof(int)*(n-1)); // 但即使是这种情况下也需要优化重叠部分的长度以与缓存行长度完全匹配。 - Aki Suihkonen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接