【问题标题】:Initialize entire array with a value in C用 C 中的值初始化整个数组
【发布时间】:2013-07-08 22:07:58
【问题描述】:

我试图初始化整个 int 数组,在通过 Stackoverflow 搜索后,我发现最好的方法是使用来自 <algorithm><vector> 标头的 std::fill_n ,但同时包含两者都会给出错误。我认为这些方法只能在 C++ 中使用,还是我做错了什么?

如何在没有任何循环的情况下(即在单个语句中)用 C 中的值初始化整个数组?

我正在开发 Fedora 14 终端并使用 gcc 进行编译。

【问题讨论】:

  • @Ryan Haining:当问题很明显是关于 C 的时候,你为什么要把 [C] 标签替换为 [C++] 标签?

标签: c arrays algorithm gcc header


【解决方案1】:

如果你有数组声明int arr[ARRAY_SIZE];,那么你可以用下面的代码填充一个int VALUEi 的声明需要在块的开头)。

int i;
for (i = 0; i < ARRAY_SIZE; i++)
   arr[i] = VALUE;

一个简单的for 循环就可以了。

【讨论】:

  • For 循环是显而易见的答案。无论如何,谢谢。
【解决方案2】:

可以按以下方式构建可重用的通用解决方案

  1. 编写一个“稳定的”memcpy_forward 函数(类似于标准 memcpy),专门用于向前复制内存区域

    void *memcpy_forward(void *dst, const void *src, size_t n)
    {
      char *pdst;
      const char *psrc;
    
      for (pdst = dst, psrc = src; n > 0; --n, ++pdst, ++psrc)
        *pdst = *psrc;
    
      return dst;
    }
    
  2. 像这样填充数组

    int a[1000];
    

    首先使用相同的值(例如,42

    a[0] = 42;
    

    然后做

    memcpy_forward(a + 1, a, sizeof a - sizeof *a);
    

此技巧可用于用任何大小的重复模式填充任何内存区域。您首先在区域的开头形成模式的初始“样本”,然后使用memcpy_forward 在所需区域中复制该模式。

【讨论】:

  • 谢谢,这真的是我学会在内存位级别复制元素的一种新方法。
【解决方案3】:

最通用的方式是写一个循环来初始化:

for (i = 0; i < some_len; ++i) {
    ary[i] = some_val;
}

如果您只需要 0,memset 或初始化将起作用。但我猜你正在寻找任意值。 memset 调用可以用单字节的任意模式填充您的数组,这可能不是您想要的。

【讨论】:

  • “任意字节模式”听起来不对。 memset 可以将每个字节设置为相同的指定值。 “任意模式”听起来像是可以将不同的字节设置为不同的值,我敢肯定这不是你的意思。
  • 不是。我的意思是你可以从 [0,(2 &lt;&lt; CHAR_BIT)-1] 中获得任何值,以字节方式填充数组,而不仅仅是 0。
  • 狡辩:你的意思是1 &lt;&lt; CHAR_BIT
【解决方案4】:

std::fill_n 确实是来自 C++ 的算法,您不能在 C 中使用。

请记住,fill_n 不会初始化数组,它会为数组的每个元素分配一个指定的值。

要在 C 中做类似的事情,您必须遍历数组的元素并为每个元素分配一个值。例如:

// Compile: gcc -std=c99 -Wall -pedantic -o test ./test.c

int main()
{
    double array[100];
    unsigned int i;

    for (i = 0; i < sizeof(array)/sizeof(array[0]); ++i)
        array[i] = 9.99;
}

如果您的数组是字节字符串,那么使用memset 可能是更好的选择——开发人员熟悉它,因此代码会更紧凑,也可能更快。例如:

// Compile: gcc -std=c99 -Wall -pedantic -o test ./test.c
#include <string.h>

int main()
{
    char array[100];
    memset(array, 1, sizeof(array)); // Set every element to 1.
}

如果你想初始化而不是赋值,那么你需要:

  • 使用零初始化器将每个元素设置为 0:int array[100] = { 0 };
  • 指定每个元素的值:int array[] = { 1, 2, 3 };

希望对您有所帮助。祝你好运!

【讨论】:

  • 这会将每个字节设置为 1,而不是数组中的每个元素都设置为 1。ints 是多个字节,因此数组的元素不会为 1。
  • 啊,废话,是的,我太傻了。我的意思是字节数组,而不是整数数组。固定。
【解决方案5】:

是的,这些是 C++ 库。您实际上可以通过查看来判断,因为 C 标准库头文件以 .h 结尾,而 C++ 标准库头文件则没有。例如,在 C 中你会使用 &lt;stdio.h&gt;,但在 C++ 中你会使用 &lt;cstdio&gt;

【讨论】:

    【解决方案6】:

    所以我相信结论是没有使用表达式初始化整个数组的预定义方法,并且 std::fill_n 只能在 C++ 中使用。

    唯一的方法是brute force for loop

    【讨论】:

      【解决方案7】:

      如果您需要使用 0 或 ~0 或任何字节值进行初始化,填充到整数的所有字节中,您可以使用 bzero() 或 memset()。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-12-22
        • 1970-01-01
        • 2017-07-21
        • 2012-11-08
        • 1970-01-01
        • 2021-04-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多