struct x {
char a[10];
char b[20];
int i;
char *c;
char *d[10];
};
我正在填充这个结构,然后使用这些值。在下一次迭代中,我想在开始重用之前将所有字段重置为 0
或 null
。
我怎样才能做到这一点?我可以使用 memset
还是必须遍历所有成员然后单独执行?
使用初始值定义结构的 const 静态实例,然后只要您想重置它,只需将此值分配给您的变量。
例如:
static const struct x EmptyStruct;
这里我依靠 static initialization 来设置我的初始值,但是如果你想要不同的初始值,你可以使用结构初始化器。
然后,每次循环你都可以写:
myStructVariable = EmptyStruct;
当您拥有现代 C (C99) 时,这样做的方法是使用复合文字。
a = (const struct x){ 0 };
这有点类似于 David 的解决方案,只是您不必担心声明一个空结构或是否声明它 static
。如果您像我一样使用 const
,编译器可以在适当的情况下自由地在只读存储中静态分配复合文字。
{ 0 }
视为默认初始值设定项。关闭该警告,这是虚假的误报。
比以上所有更好的是使用标准 C 规范进行结构初始化:
struct StructType structVar = {0};
这里都是零位(永远)。
{}
。 gcc 开发人员似乎unsure whether C++ is supposed to support {0}
,我自己并不熟悉标准的那部分。
{0}
或 {}
存在太多可移植性问题。不确定 C & C++ 标准在这个问题上是明确的并且是同步的,但显然编译器不是。
struct StructType structVar = malloc (sizeof(StructType)); structVar ={0}
在 C 中,使用 memset
将 struct
的内存归零是一种常见的习惯用法:
struct x myStruct;
memset(&myStruct, 0, sizeof(myStruct));
从技术上讲,我不认为这是可移植的,因为它假设机器上的 NULL
指针由整数值 0 表示,但它被广泛使用,因为在大多数机器上都是这种情况。
如果您从 C 迁移到 C++,请注意不要在每个对象上都使用此技术。 C++ 仅在没有成员函数和继承的对象上才允许这样做。
如果你有一个 C99 兼容的编译器,你可以使用
mystruct = (struct x){0};
否则你应该做大卫赫弗南写的,即声明:
struct x empty = {0};
在循环中:
mystruct = empty;
您可以将 memset
与结构的大小一起使用:
struct x x_instance;
memset (&x_instance, 0, sizeof(x_instance));
memset
是一个选项,但是在使用它时,你必须确保写入的内存与第三个参数的大小完全相同,这就是为什么最好参考实际对象的大小,而不是对象的大小你知道它当前的类型。 IOW memset (&x_instance, 0, sizeof(x_instance));
是一个更好的选择。顺便说一句:(void*)
演员表在 C++ 中也是多余的。
我相信您可以将空集 ({}
) 分配给您的变量。
struct x instance;
for(i = 0; i < n; i++) {
instance = {};
/* Do Calculations */
}
struct x myX;
...
memset(&x, 0, sizeof(myX));
我询问了工作中的编译器工程师哪个选项更好(memset 与 {0})。他没有给出我的意见,而是将我指向 Compiler Explorer。看看这三个选项是如何编译出来的很有趣:
https://godbolt.org/z/bPfKeG9Yh
这是代码的预览:
// Type your code here, or load an example.
#include "string.h"
struct MyStruct {
int age;
int sin;
char *name;
int cats;
char something[64];
};
const struct MyStruct empty_struct = {0};
int test() {
struct MyStruct blah = {0};
memset(&blah, 0, sizeof(blah));
blah = empty_struct;
blah.age = 99;
blah.sin = 123456789;
}
编译器根据结构的成员类型对如何将内存归零做出不同的决定。例如,尝试注释掉 something
或选择非 x86 目标。
带 NULL 的 Memset 是危险的函数。
对于大多数简单的数据结构,通过这种方式更好地使用 C++ >>
template<class T>
void Null_MyType(T &obj)
{
constexpr T o_null = T{};
obj = o_null;
}
https://i.stack.imgur.com/Xwjhi.png
来自gnu11的惊喜!
typedef struct {
uint8_t messType;
uint8_t ax; //axis
uint32_t position;
uint32_t velocity;
}TgotoData;
TgotoData tmpData = { 0 };
没有什么是零。
不定期副业成功案例分享
0
,这是否比使用memset
更好?memset
让我感觉很脏。我更愿意让编译器尽可能地担心内存布局。严格来说,memset
的这种使用是不可移植的,但实际上,如果您曾经在任何重要的地方编译过您的代码,我会感到震惊。因此,如果您愿意,您可以安全地使用 memset。