如何静态初始化结构体数组?

9
struct A{
    int a; int b;
};
static const struct A a = {.a1 = 1, .a2 = 42};

struct B{
    struct A[666][510]
};
static const struct B b;

我想用a的副本来初始化b,但我不能使用memcpy()操作静态常量。而且我需要b是静态常量,因为这样它就会被放入闪存而不是RAM内存。
如何解决这个问题呢?编译器是arm-none-eabi-gcc,使用了-std=c89选项。

请参考 https://dev59.com/M3zaa4cB1Zd3GeqPKw7s 的答案。 - Brave Sir Robin
4
“.a1 = 1”:未知的字段,并且不符合C89标准。 - BLUEPIXY
1
检查链接脚本以查找放入闪存的部分,并添加“section”属性将其放置在该部分中。 - Some programmer dude
所以你想要666*510份相同数据的副本?而且你想让它是const的?我只是好奇这会有什么用处。 - John Zwinck
@BLUEPIXY,它是一种奇怪的ansi c和gnu扩展混合体。例如for(int i = 0; i < 5; i ++)不能编译。 - Vorac
@JohnZwinck,这是默认配置。使用这些默认值的模块很蠢,并且希望它们都被分配。此外,稍后我们将把它们更改为略微有意义的值。 - Vorac
3个回答

1
我建议您将这些数组放在一个单独的模块中,以实现封装。然后,在该模块内部,您不需要将B设为const,而是应将其设置为static。任何对这些数据的访问都必须通过像这样的getter和setter进行:

<strong>mydata.h</strong>

#define BA_SIZE 666

struct A{
    int a; int b;
};

struct B{
    struct A stuff[BA_SIZE];
};

void init(void);
struct A * getB(unsigned int i);
void setB(unsigned int i, struct A element);

<strong>mydata.c:</strong>

#include "mydata.h"

static const struct A a = {.a = 1, .b = 42};
static struct B b;

void init(void)
{
    int i;
    for(i=0; i&ltBA_SIZE; i++) {
        b.stuff[i] = a;
    }
} 

struct A * getB(unsigned int i)
{
    return(&b.stuff[i]);
}

void setB(unsigned int i, struct A element)
{
    if (i > BA_SIZE) { return; }
    b.stuff[i].a = element.a;
    b.stuff[i].b = element.b;
}


<strong>main.c:</strong>
#include &ltstdio.h>
#include "mydata.h"

int main(void)
{
    init();
    unsigned int num=1;
    struct A * something = getB(num);
    printf("element [%u] a=%i b=%i \n", num, something-&gta, something-&gtb);

    return(0);
}



将数据定义为 static const 可以让链接器将其放入闪存中,而不是宝贵的 RAM 中。因为我只需要读取这些数据,所以我可以这样做。另一方面,对于可变数据,您的示例看起来很棒。 - Vorac

1

虽然以下方法仅适用于您指定的尺寸(666 x 510),但您可以尝试这样做:

#define X001 {1,42}
#define X002 X001,X001
#define X004 X002,X002
#define X008 X004,X004
#define X016 X008,X008
#define X032 X016,X016
#define X064 X032,X032
#define X128 X064,X064
#define X256 X128,X128

#define Y001 {X256,X128,X064,X032,X016,X008,X004,X002}
#define Y002 Y001,Y001
#define Y004 Y002,Y002
#define Y008 Y004,Y004
#define Y016 Y008,Y008
#define Y032 Y016,Y016
#define Y064 Y032,Y032
#define Y128 Y064,Y064
#define Y256 Y128,Y128
#define Y512 Y256,Y256

static const struct A a = X001;
static const struct B b = {{Y512,Y128,Y016,Y008,Y002}};

有点凌乱,但这是前进的方式。他们说宏是语言的支撑。非常感谢! - Vorac

0

在 Linux 上,这可以使用 gcc -std=c89 进行编译(不知道关于 ARM 交叉编译器)

typedef struct A{
    int a; int b;
} TA;
typedef struct ARR3 { TA a[3]; } TARR3;
typedef struct ARR33 { TARR3 b[3]; } TARR33;
static const TA a = {.a = 1, .b = 42};
TARR33 aa = { .b[0] = { .a[0] = {.a = 1, .b = 1}, .a[1] = {.a = 2, .b = 2}, .a[2] = {.a = 3, .b = 3} }, .b[1] = { .a[0] = {.a = 4, .b = 4}, .a[1] = {.a = 5, .b = 5}, .a[2] = {.a = 1, .b = 2} }, .b[2] = { .a[0] = {.a = 1, .b = 1}, .a[1] = {.a = 1, .b = 2}, .a[2] = {.a = 1, .b = 2} } };
main() { return 0; }

嗯,是的,但你仍然需要输入所有的数字。在我的情况下,数组比3x3大得多。看起来这个是唯一的答案。但它太丑了! - Vorac

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接