在指定的初始化程序中复制数组

时间:2013-11-22 00:15:03

标签: c arrays c99

我正在尝试使用指定的初始化程序初始化const struct。但是,struct元素之一是固定宽度的数组。我已经有了我想用适当大小的另一个固定宽度数组初始化数组的内容。

有没有办法用指定的初始化程序执行此操作?我想要完成的一个简单(失败的例子)如下所示。

struct foo {
    uint8_t array1[4];
    uint8_t array2[4];
}

uint8_t array[4] = {
    1, 2, 3, 4
};

struct foo const bar = {
   .array1 = array,     // incompatible pointer to integer conversion
   .array2 = { *array } // only copies the first element
};

3 个答案:

答案 0 :(得分:1)

简短的回答:你做不到。 C不复制数组(不使用(标准库)函数)。警告来自这样一个事实:即使它们是静态的或不变的,您也不能将数组作为一个整体分配。当数组用作赋值中的r值时,它会衰减到指针,因此无法分配给另一个数组(作为一个整体)。

最简单的方法是使用memcpy,但显然必须在函数内部。

答案 1 :(得分:1)

如果bar具有全局作用域,或者声明为静态,则无论使用的成员是否为数组,您都无法使用指定的初始值设定项从非立即值初始化。

但是,如果:

  1. bar在某个函数的堆栈上声明,
  2. 你的固定大小的数组确实只有4个元素,
  3. 然后你可能会得到这样的东西:

    #include <stdio.h>
    #include <stdint.h>
    
    struct foo {
        uint8_t array1[4];
        uint8_t array2[4];
    };
    
    #define ARRAY_INIT(a) { a[0], a[1], a[2], a[3] }
    
    int main (int argc, char **argv) {
        uint8_t arr_init[4] = {
            1, 2, 3, 4
        };
        struct foo const bar = {
            .array1 = ARRAY_INIT(arr_init),
            .array2 = ARRAY_INIT(arr_init),
        };
        printf("%d, %d\n", bar.array1[0], bar.array2[3]);
        return (0);
    }
    

    初始化程序数组必须出现在堆栈帧中初始化的内容之前。或者它可能来自函数参数。

    当然如果你的数组比这个大得多,那么使用这样的宏确实会非常混乱。

答案 2 :(得分:0)

虽然您可能无法通过从另一个阵列复制来初始化阵列,但使用预处理器宏可能会有所帮助:

#define ARRAY_INIT {1, 2, 3, 4}

struct foo const bar = {
   .array1 = ARRAY_INIT,
   .array2 = ARRAY_INIT
};