静态初始化的结构体自引用

3

我有一个简单的结构,定义如下:

typedef struct { 
    int index;
    double* arrayToRead;
} my_struct;

我想初始化一个结构体数组,使它们变成这样:
double decimals[2] = {1.0, 2.0};

my_struct[2] = {
    {0, &decimals[0]},
    {1, &decimals[1]}
};

我需要静态初始化这个结构体数组。

我能否在静态初始化时引用先前定义的成员,像这样:

my_struct[2] = {
    {0, &decimals[index]},
    {1, &decimals[index]}
};

“index”指的是在“decimals”左侧定义的index值吗?
4个回答

7
如果您有现代的C编译器(也称为C99),您可以使用P99来进行代码展开。类似这样的:
#define INIT_ELEMENT(NAME, X, I) [I] = { \
  .index = I,                            \
  .arraytoread = &decimals[I]            \
}
#define INIT_ELEMENTS(N) P99_FOR(, N, P00_SEQ, INIT_ELEMENT, P99_DUPL(N,))

然后

my_struct A[] = { INIT_ELEMENTS(2) };

应该扩展为您喜欢的初始化程序。

(这里第一个宏定义了要重复的代码,仅使用其参数中的I,即调用的索引。在第二个宏中,P00_SEQ表示这是由逗号分隔的。)


哦哦哦...我之前没听说过那个。不错。 - dmckee --- ex-moderator kitten
+1,但是无论如何,相比在vim中保存宏、应用n次并最终得到可读性较好的结果,这种方法有什么优势呢? - ninjalj
@ninjalj,你什么时候把2改成42 - Jens Gustedt
@ninjalj,我的理解是OP想要通过类似{i,&decimals[i]}的一系列方式进行初始化,使得索引字段初始化为当前数字,指针值被视为decimals数组的第i个元素。我在这里提供的只是指定初始化程序语法相同的内容,不是吗? - Jens Gustedt
当然,我只是发现纯C99语法(就像Oli的答案中那样)更易读,并且您始终可以使用编辑器宏来代替P99_FOR中的重复。我想这只是个人口味问题(我不习惯使用P99)。 - ninjalj
显示剩余2条评论

5

编号*

如果你非常着急,你可以设计一个宏来完成这个任务:

#define DEFINE_ELEMENT(i) {(i), &decimals[(i)]}
my_struct m[2] = {
    DEFINE_ELEMENT(0),
    DEFINE_ELEMENT(1)
};
#undef DEFINE_ELEMENT
*或者,如@Jens在他的答案中指出的那样,对于C99是“是”。


注:该句是关于C语言中_Bool数据类型的说明。

接近了,但答案是肯定的,请看我的回答 :) - Jens Gustedt
@Jens:我没有想到那个(所以你的有趣答案+1)。从技术上讲,它仍然是“不”,因为这不是OP所想要的语法... - Oliver Charlesworth

0

天上飞的是什么?是一只鸟!不,是一架飞机!不,是代码生成人!

enter image description here

或者——开个玩笑——我不知道是否有内置功能支持这一点,但您始终可以使用外部工具为您编写初始化代码。


基本上,您可以使用某种方便的语言编写脚本,输出一个 C 代码片段来定义结构并声明变量,然后使用 C 预处理器的 #include 功能将生成的文件拖入您的代码中。

您需要让构建管理器知道这个需求。在 make 中,它看起来应该是这样的:

cfile.o: cfile.c mystruct.c

my_struct.c:
        awk -f generate_my_struct.awk > my_struct.c

3
这里不是发表讽刺言论的地方。你的嘲讽语气会分散注意力,影响你回答中有用的内容(“不,使用代码生成”)。 - Adam Rosenfield
嗯,@Adam,这是一个真正的建议。当然不是任何人的首选,但它是解决问题的完美有效方法。也许我的幽默感今天有点调皮。 - dmckee --- ex-moderator kitten
我认为这是一个完全有效的解决方案,但我不同意你提出的方式。 - Adam Rosenfield
错误,什么?那从哪儿冒出来的?无论如何,我已经取消了我的差评。 - Adam Rosenfield

0

我认为你需要给你的新数组命名

my_struct my_array[2] = {
  {0, &decimals[my_array[0].index]},
  {1, &decimals[my_array[1].index]}
};

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