【问题标题】:Initialize array with struct of const data使用 const 数据结构初始化数组
【发布时间】:2014-11-27 08:34:14
【问题描述】:

我的案例与stackoverflow.com/questions/16676973有些相似,但是由于缺乏知识,我无法从中吸取重要的教训...

我想要实现的是在编译时将常量图像数据加载到内存中(不确切知道每个图像的大小)并获取每个图像的标识符数组,以便我可以随时在代码中访问它们。 理想的方法是指向每个图像开头的指针数组,但是有一个问题是我以后如何确定每个图像的确切大小。当我调用 images[i] 时,sizeof(imagedatatype) 是否会根据 i 改变...(我猜 - 不。那么如何?)

我的尝试是这样的:

typedef struct _imagedatatype {
    uint8_t imageId;
    uint8_t dataofoneimage[]
} imagedatatype;
const imagedatatype images [] = {
    {1,{A, ,L,O,T, ,O,F, ,C,O,N,V,E,R,T,E,D, ,I,M,A,G,E, ,D,A,T,A, ,I,N, ,H,E,X}}, 
    {2,{A, ,L,O,T, ,O,F, ,C,O,N,V,E,R,T,E,D, ,I,M,A,G,E, ,D,A,T,A, ,I,N, ,H,E,X}}
//of course, data is fake here, just for illustration purposes, normally it is 0x00, 0x0c, etc
};

当然,它会引发错误,例如“数组的初始化程序太多......”。

简而言之 - 我觉得那里有很多错误,主要是意识形态上的,但正如我所说,我是 C 新手,所以我正在努力快速学习所有这些复杂的东西..

请帮忙。

【问题讨论】:

    标签: c arrays struct initialization constants


    【解决方案1】:

    不幸的是,N1570 6.7.2.1.18 说:

    作为一种特殊情况,具有多个命名成员的结构的最后一个元素可能 数组类型不完整;这称为灵活数组成员。在大多数情况下, 灵活的数组成员被忽略。特别是,结构的大小就像 灵活的数组成员被省略了,除了它可能有更多的尾随填充比 遗漏意味着

    这意味着您不能使用此方法,因为它无法正确计算数组中单个元素的地址。

    您可以通过将图像数据与结构分离来解决此问题:

    typedef struct _imagedatatype {
        uint8_t imageId;
        size_t size;
        uint8_t const * data;
    } imagedatatype;
    uint8_t const img1data [] = { ... };
    uint8_t const img2data [] = { ... };
    const imagedatatype images [] = {
         { 1, sizeof img1data, img1data },
         { 2, sizeof img2data, img2data },
    }
    

    如果你绝对想用结构定义图像数据,你可以使用 X-macros 来绕过这个限制,但底层方法仍然是相同的。 X 宏可能会变得混乱,因此请注意。

    【讨论】:

    • 是的,我知道可以这样做,我以前也是这样做的,但对我来说看起来有点尴尬(为每个数据块显式命名),因此我尝试了对它们进行“数组化”,因为无论如何它们都会并排放置在内存中的某个位置,然后我真正需要知道的只有指向这些结构的头部的指针。我也知道当 'dataofoneimage' 的大小确切知道时它工作得很好。知道在 C 中几乎所有事情都可以完成,我希望它应该很容易。令我惊讶的是,它不是......
    • @DzintarsLicis 是的,在这种情况下,C 语法有点不灵活。对我来说,通常最有效的方法是编写 Python 脚本,它接受输入文件并输出 .c 文件。这样我也可以用它过滤掉任何不必要的数据,如果它是用于内存有限的嵌入式系统的话。
    【解决方案2】:
    typedef struct _imagedatatype {
        uint8_t imageId;
        uint8_t dataofoneimage[];   // you missed the trailing ; here
    } imagedatatype;
    

    dataofoneimage 成员这里没有指定数组大小是一个特殊的 C 功能,称为 灵活数组 成员(参见 c99,6.7.2.1p16 的语义)。它只能在你的结构声明的末尾(你正确地做了),但它不能在声明时初始化。

    使用malloc 分配此结构和赋值或复制以填充其dataofoneimage 成员。

    【讨论】:

      猜你喜欢
      • 2014-08-08
      • 2010-09-22
      • 2013-01-17
      • 2016-02-18
      • 2018-01-16
      • 2015-07-29
      • 1970-01-01
      • 2014-01-21
      • 2020-02-15
      相关资源
      最近更新 更多