如何在C语言中初始化结构体内的常量变量?

14

我写了一个结构体

struct Tree{
    struct Node *root;
    struct Node NIL_t;
    struct Node * const NIL;    //sentinel
}

我想要

struct Node * const NIL = &NIL_t;

我无法在结构体内部初始化它。 我使用的是MSVS,语言是C而不是C++。 我知道在C ++中可以使用初始化列表。 如何在C中实现?


2
出于好奇,为什么你需要一个NIL_t的值和一个指向NIL的指针?这似乎有点多余。独立地说,这是一个有趣的问题! - templatetypedef
正确。你没有使用C++,所以你不能这样做。 - Lightness Races in Orbit
4个回答

24
如果您正在使用C99,您可以使用指定的初始化器来完成这个操作:
struct Tree t = { .root = NULL, .NIL = &t.NIL_t };

这仅在C99中有效。我已经在gcc上进行了测试,看起来运行良好。

1
+1 这实际上会成为一个不错的宏定义:#define TreeDecl(id, rt) struct Tree id = { .root = rt, .NIL = &id.NIL_t } - Chris Lutz
4
只要0是结构体Node中第一个字段的有效初始化值,在C89中,您可以执行struct Tree t = { NULL, { 0 }, &t.NIL_t }; - Chris Dodd
或者,继续@Chris Dodd的评论,您可以重新排列结构体,使NIL成员在NIL_t成员之前,然后使用struct Tree t = { NULL,&t.NIL_t }; - caf

2

对于那些寻求简单例子的人,这里有一个:

最初的回答:

#include <stdio.h>

typedef struct {
    const int a;
    const int b;
} my_t;

int main() {
   my_t s = { .a = 10, .b = 20 };
   printf("{ a: %d, b: %d }", s.a, s.b);
}

"最初的回答":产生以下输出:

(产生以下输出)

{ a: 10, b: 20 }

1

结构体定义了一个数据模板,但本身没有数据。由于它没有数据,因此无法初始化。

另一方面,如果您想声明一个实例,您可以对其进行初始化。

struct Tree t = { NULL, NULL, NULL };

1
NIL_t 是一个 struct Node,而不是 struct Node *,所以它可能不会被初始化为 NULL。我建议您创建一个 struct Tree *init(...) 函数(或者如果您喜欢的话,可以创建一个 void init(struct Tree *t, ...) 函数或宏)来为您完成这种工作。 - Chris Lutz
@Chris:你说得对。我可能错过了那个。我想在两个结构体都被声明之后,你才能将一个结构体分配给另一个结构体。 - Jonathan Wood
@Jonathan - 对于嵌套的 struct,你可以使用 struct Tree t = { NULL, { /* 在此处放置 struct Node 的内容 */ }, NULL }(或者对于最后一个,使用 &t.NIL_t)。 - Chris Lutz
@Chris:一开始我也是这么想的。但如果该成员是相同类型的结构体,那么语法将会无限递归。不,我认为这样行不通。 - Jonathan Wood
@Jonathan - 不是的。这是一个struct Tree内部的struct Node。在这种情况下不会无限递归。(如果它是无限递归的话,那就是个问题了。但这不是OP的情况。) - Chris Lutz
显示剩余2条评论

0

也许这样就足够了吧?

struct {
    struct Node * const NIL;
    struct Node *root;
    struct Node NIL_t;
 } Tree = {&Tree.NIL_t};

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