C语言中如何从已有数组静态初始化另一个数组
C标准要求全局常量对象的静态初始化器必须是编译期常量表达式,数组名在初始化语境下会退化为指针,因此无法直接用数组名作为另一个数组的初始化器,你可以根据编译环境选择以下方案:
方案1:纯标准C实现(无编译器扩展、无宏)
直接显式编写两个数组的初始化列表,配合编译期断言保证两个数组的大小、内容完全一致,避免后续修改出现不一致问题:
#include <stdint.h> #include <assert.h> const uint8_t array_1[] = {1, 2, 3}; const uint8_t array_2[] = {1, 2, 3}; // 编译期校验数组大小一致 _Static_assert(sizeof(array_1) == sizeof(array_2), "Two arrays have different size"); // C23及以上标准可直接用编译期内存比较校验内容一致 #if __STDC_VERSION__ >= 202311L _Static_assert(__builtin_memcmp(array_1, array_2, sizeof(array_1)) == 0, "Two arrays have different content"); #endif
方案2:GCC/Clang 环境实现(无宏、编译期初始化)
如果你的项目仅使用GCC或Clang编译器,可以利用编译器内置的编译期内存复制能力直接完成初始化,无需重复编写初始化列表:
#include <stdint.h> const uint8_t array_1[] = {1, 2, 3}; const uint8_t array_2[] = __builtin_memcpy((uint8_t[sizeof(array_1)]){}, array_1, sizeof(array_1));
该写法会在编译阶段就完成array_1到array_2的内容复制,不会产生任何运行期开销,符合静态常量缓冲区的使用要求。
方案3:跨编译器宏实现(可选)
如果可以接受宏实现,你可以把共用的初始化列表封装为宏,避免重复代码:
#include <stdint.h> #include <assert.h> #define ARRAY_INIT_VAL {1, 2, 3} const uint8_t array_1[] = ARRAY_INIT_VAL; const uint8_t array_2[] = ARRAY_INIT_VAL; _Static_assert(sizeof(array_1) == sizeof(array_2), "Two arrays have different size");
内容的提问来源于stack exchange,提问作者kokopelli
相关产品推荐
相关产品推荐

