非常大的C结构的分段初始化

问题描述 投票:1回答:3

我的嵌入式应用程序存储(在ROM,const中)非常大,非常嵌套的结构。我正在寻找一种初始化它的整洁方法。所以改为写作:

typedef struct {
    uint32_t    n1;
    float       fArr[5];
    struct {
        char    cArr[1000];
        int32_t n3;
    }subStruct;
    // ... and on and on 
}Config_t;

const Config_t cfg = {
    .n1 = 5,
    .fArr = {1.0, 2.0, 0, -5.6, 8.8},
    .subStruct.cArr = {1,1,1,2,2,2,3,3,3/*etc*/},
    .subStruct.n3 = 3
};

使用类似的东西:

const float fArrAux[5] = { 1.0, 2.0, 0, -5.6, 8.8 };
const char cArrAux[1000] = { 1,1,1,2,2,2,3,3,3/*etc*/ };

const Config_t cfg = {
    .n1 = 5,
    .fArr = fArrAux,            // ?
    .subStruct.cArr = cArrAux,  // ?
    .subStruct.n3 = 3
};

有没有推荐的方法来做到这一点,以便主结构在内存中保持连续(不包括成员填充)(它在闪存中,所以我想在一次传递中刻录它)。

此外,这种设置中的辅助定义(fArrAux,cArrAux)是否会消耗内存(因此占用空间的两倍)?

谢谢

c struct const initializing
3个回答
2
投票

如果您只是想在视觉上分离长数组初始值设定项,您可以考虑将它们定义为宏:

#define CFG_FARR             { 1.0, 2.0, 0, -5.6, 8.8 }
#define CFG_SUBSTRUCT_CARR   { 1, 1, 1, 2, 2, 2, 3, 3, 3, /*etc*/ }

const Config_t cfg = {
    .n1 = 5,
    .fArr = CFG_FARR,
    .subStruct.cArr = CFG_SUBSTRUCT_CARR,
    .subStruct.n3 = 3
};

2
投票

请注意,在C中,可执行代码总是出现在函数内部。

这两种初始化(假设它是static或全局数据,在任何函数代码之外)都是在构建时发生的,并且实际上正在初始化某种code segment

只有当.fArr.subStruct.cArr是指针(不是数组)时,你的第二个变体才有意义(并且应该编译)。因此,它没有编译:

e.c:18:13: error: incompatible types when initializing type ‘float’ 
                  using type ‘const float *’
     .fArr = fArrAux,            // ?
             ^~~~~~~

您可以考虑将构建过程更改为例如生成一些C定义,例如在一些大型生成的.c文件中包含类似于第一个变体的东西。


1
投票

您可以将实际数据放在可以使用某些外部工具生成或创建的文件中,这也可以让您在将数据作为初始化程序分配给结构和数组之前检查数据的正确性:

const Config_t cfg = {
    .n1 = 5,
    .fArr = 
#include "fArrData.txt"
    ,
    .subStruct.cArr = 
#include "cArrData.txt"
    ,
    .subStruct.n3 = 3
};

免责声明:我没有测试过这个。在其他情况下,我写了一个小程序来为我做这个。

© www.soinside.com 2019 - 2024. All rights reserved.