如何将结构体初始化为null?

5

我有一个结构体,其中包含两个相同类型的其他结构体,我想将其初始化为两个都为NULL。我该怎么做?我尝试了下面的代码,但在使用gcc编译器时会出现警告。

#include <stdio.h>

typedef struct Segment {
    int microseconds;
} Segment;

typedef struct Pair {
    Segment mark;
    Segment space;
} Pair;

int main()
{
    Pair mark_and_space = { .mark = NULL, .space = NULL };

    return 0;
}

编译器警告:

main.c:14:5: warning: initialization makes integer from pointer without a cast [enabled by default]                                                   
 Pair mark_and_space = { NULL,  NULL };                                                                                                           
 ^                                                                                                                                                
main.c:14:5: warning: (near initialization for 'mark_and_space.mark.microseconds') [enabled by default]                                               

main.c:14:5: warning: initialization makes integer from pointer without a cast [enabled by default]                                                   
main.c:14:5: warning: (near initialization for 'mark_and_space.space.microseconds') [enabled by default] 

2
将NULL更改为0,因为标记和空格类型是int。 - Ihdina
7个回答

6

您无法这样做。NULL是一个指针,其值设置为零,但您的markspace属性不是指针值。在您当前的代码中,它们都将是值类型,作为您的Pair结构的一部分分配。

将变量更改为Segment *而不是Segment,然后您将能够将它们设置为NULL。


5
为了初始化两个子结构,每个子结构都包含一个单独的int成员,并且将它们都设置为最接近NULL的值,即将所有int初始化为“0”,您可以使用以下代码:
#include <stdio.h>

typedef struct Segment {
    int microseconds;
} Segment;

typedef struct Pair {
    Segment mark;
    Segment space;
} Pair;

int main(void)
{
    Pair mark_and_space = { {0}, {0} };

    return 0;
}

如果您想将它们初始化为NULL,假设您考虑的是指针(只有指针可以干净地初始化为NULL),那么请参见其他答案,它们基本上都说“如果您想初始化指针值,则初始化指针而不是整数”。

1
#include <stdio.h>

typedef struct Segment {
    int microseconds;
} Segment;

typedef struct Pair {
    Segment mark;
    Segment space;
} Pair;

int main()
{
    Pair mark_and_space = { .mark.microseconds = (int) NULL, 
                            .space.microseconds =(int) NULL };
    return 0;
}

如果你仍然想将其设置为NULL,请忽略其他答案。

0
你之所以会收到这些错误,是因为NULL是一个指针。你不能将指针赋值给Segment。解决方法是将一对Segment改为Segment *。但这样你就需要负责内存分配了。

0

由于 Pair 字段不是指针,使用 NULL 初始化结构体并不是一个好的选择。但是如果你只想将字段设置为零,可以尝试使用更多的大括号:

Pair mark_and_space = { .mark = {3}, .space = {0} };

这行代码在我的MinGW编译器上没有任何警告。我将mark.milliseconds设置为3,只是为了演示如何将任意初始值设置为内部毫秒字段。


0

你不能将结构体初始化为null。不过,你可以将结构体的指针初始化为null。根据POSIX标准(我强调的部分):

NULL

空指针常量。[CX] ⌦该宏应扩展为一个整数常量表达式,其值为0转换为type void *⌫。

请注意那个类型以及为什么它与你的定义不兼容。你可以将成员更改为Segment * (并自己malloc堆叠变量),或者静态初始化它们:

Pair mark_and_space = { { }, { } };
/* v---------------------^    ^
  default to 0, but you can choose different value(s) */

你正在阅读哪个标准?C11标准,ISO/IEC 9899:2011 §7.19 **通用定义<stddef.h>**中写道:¶3 这些宏是: NULL 它扩展为实现定义的空指针常量; …. 这与你引用的内容不符。 C90和C99都没有说过你声称引用的内容; 两者都说了C11所说的话。你的空括号表示法在C中也无效,但在C++中有效。你在C问题中引用C++标准吗? - Jonathan Leffler
1
哦,好的 - 你在引用 POSIX 标准,并且忽略了标记,这些标记显示规则是 C 标准的扩展。我已经添加了这些标记,并指定你引用的是 POSIX 标准而不是 C 标准,突然间你的引用就变得干净了。空括号初始化在标准 C 中仍然无效。 - Jonathan Leffler

0
int main()
{
    Pair mark_and_space;
    mark_and_space.mark = NULL;
    mark_and_space.space = NULL;
    return 0;
}

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