将struct初始化/重置为零/ null

har*_*ari 86 c struct initialization

struct x {
    char a[10];
    char b[20];
    int i;
    char *c;
    char *d[10];
};
Run Code Online (Sandbox Code Playgroud)

我正在填充此结构,然后使用值.在下一次迭代中,我想在重新开始重用之前0null之前重置所有字段.

我怎样才能做到这一点?我可以使用memset或者必须通过所有成员然后单独进行吗?

Dav*_*nan 100

使用初始值定义struct的const静态实例,然后只要您想重置它,就可以将此值分配给变量.

例如:

static const struct x EmptyStruct;
Run Code Online (Sandbox Code Playgroud)

这里我依靠静态初始化来设置我的初始值,但如果你想要不同的初始值,你可以使用struct初始化器.

然后,每次循环你都可以写:

myStructVariable = EmptyStruct;
Run Code Online (Sandbox Code Playgroud)

  • @hari我自己更喜欢这个approch.使用`memset`让我觉得很脏.我更愿意让编译器尽可能地担心内存布局.严格来说,使用`memset`是不可移植的,但实际上如果你编写代码的任何地方,我会感到震惊.因此,如果您愿意,可以安全地使用memset. (9认同)
  • @hari,从概念上讲更好,因为您提供了默认的初始化值(类似于对象工厂模式)。 (2认同)

Jen*_*edt 80

当你有现代C(C99)时,做这样的事情的方法是使用复合文字.

a = (const struct x){ 0 };
Run Code Online (Sandbox Code Playgroud)

这有点类似于David的解决方案,只是您不必担心声明空结构或是否声明它static.如果你const按照我的方式使用,编译器可以自由地在只读存储中静态分配复合文字.

  • "缺少初始化程序"警告真的是假的.C标准准确规定了必须发生的事情,并将`{0}`视为默认初始化程序.切换警告,这是虚假的误报. (3认同)
  • “const”真的有必要吗?当然,编译器可以正确优化它,因为它是一个仅用于此分配的文字。 (2认同)

use*_*313 54

比以上所有更好的是使用标准C规范进行结构初始化:

struct StructType structVar = {0};
Run Code Online (Sandbox Code Playgroud)

这里都是零(永远).

  • 我不认为你每次都可以在循环中做到这一点 (12认同)
  • @Cyan您可以在C++中使用`{}`.gcc开发人员似乎[不确定C++是否应该支持`{0}`](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119#c22)并且我不熟悉那部分自己的标准. (3认同)
  • 这确实可以起作用.但不幸的是,gcc和g ++抱怨它.gcc生成警告,而g ++生成错误.我知道gcc和g ++在这方面有错(它们应该遵循标准C规范),但是,为了良好的可移植性,必须考虑这种限制. (2认同)

tem*_*def 33

在C中,将struct使用的内存清零是一种常见的习惯用法memset:

struct x myStruct;
memset(&myStruct, 0, sizeof(myStruct));
Run Code Online (Sandbox Code Playgroud)

从技术上讲,我不相信这是可移植的,因为它假设NULL机器上的指针由整数值0表示,但它被广泛使用,因为在大多数机器上都是这种情况.

如果从C迁移到C++,请注意不要在每个对象上使用此技术.C++仅对没有成员函数且没有继承的对象具有合法性.

  • @KevinM是的,符号"0"总是对应于NULL指针,即使它是全零; 但如果使用memset将这些位设置为零,则编译器无法执行任何操作. (8认同)
  • C标准规定NULL始终为0.如果设计机器使得预定的无效地址不是字面上的0,则该体系结构的编译器必须在编译期间进行调整. (2认同)

Rud*_*uis 17

如果您有符合C99标准的编译器,则可以使用

mystruct = (struct x){0};
Run Code Online (Sandbox Code Playgroud)

否则你应该做David Heffernan所写的,即声明:

struct x empty = {0};
Run Code Online (Sandbox Code Playgroud)

在循环中:

mystruct = empty;
Run Code Online (Sandbox Code Playgroud)


Die*_*lla 5

您可以使用memset结构的大小:

struct x x_instance;
memset (&x_instance, 0, sizeof(x_instance));
Run Code Online (Sandbox Code Playgroud)