你如何比较结构C中的平等?

如何比较标准C中两个相等结构的实例?

C没有提供语言设施来做到这一点 – 你必须自己做,并按照成员比较每个结构成员。

您可能会试图使用memcmp(&a, &b, sizeof(struct foo)) ,但它可能无法在所有情况下工作。 编译器可能会将alignment缓冲区空间添加到结构中,并且在位于缓冲区空间中的内存位置处find的值不保证是任何特定的值。

但是,如果在使用callocmemset之前使用callocmemset ,则可以使用memcmp进行浅层比较(如果结构包含指针,则只有在指针指向的地址相同时才匹配)。

如果你做了很多,我会build议编写一个比较两个结构的函数。 这样,如果你改变结构,你只需要在一个地方改变比较。

至于如何做到这一点….你需要单独比较每个元素

您不能使用memcmp比较由于结构中的字段之间的潜在随机填充字符而造成的相等的结构。

  // bad memcmp(&struct1, &struct2, sizeof(struct1)); 

以上将会失败的结构像这样:

 typedef struct Foo { char a; /* padding */ double d; /* padding */ char e; /* padding */ int f; } Foo ; 

您必须使用成员智能比较才能安全。

注意,只要不初始化所有成员(一次),就可以在非静态结构上使用memcmp()而不用担心填充。 这是由C90定义的:

http://www.pixelbeat.org/programming/gcc/auto_init.html

在一般情况下@Greg是正确的,必须写明确的比较函数。

在以下情况下可以使用memcmp

  • 该结构不包含可能为NaN浮点字段。
  • 该结构不包含填充(使用-Wpadded和clang来检查这个)或者在初始化时使用memset显式初始化结构。
  • 没有成员types(如Windows BOOL )具有不同但等同的值。

除非你正在为embedded式系统编程(或者编写一个可能在其上使用的库),否则我不会担心C标准中的一些特殊情况。 32位或64位设备上不存在near vs. far指针的区别。 没有非embedded式系统,我知道有多个NULL指针。

另一种select是自动生成相等函数。 如果你用简单的方式来定义你的结构定义,那么可以使用简单的文本处理来处理简单的结构定义。 您可以使用libclang作为一般情况 – 因为它使用与Clang相同的前端,它可以正确处理所有转angular情况(禁止错误)。

我还没有看到这样的代码生成库。 不过,看起来比较简单。

但是,这种生成的相等函数在应用程序层面往往会做错误的事情。

memcmp不比较结构, memcmp比较二进制,并且结构中总是有垃圾,所以它总是比较出来。

按元素比较元素的安全性,不会失败。

如果结构只包含原语,或者如果你对严格的平等感兴趣,那么你可以做这样的事情:

 int my_struct_cmp(const struct my_struct * lhs,const struct my_struct * rhs)
 {
    返回memcmp(lhs,rsh,sizeof(struct my_struct));
 }

但是,如果结构体包含指向其他结构体或联合体的指针,则需要编写一个函数,以正确地比较原语,并根据需要对其他结构进行比较调用。

但是请注意,您应该使用memset(&a,sizeof(struct my_struct),1)来将结构的内存范围归零,作为ADT初始化的一部分。

这取决于你问的问题是:

  1. 这两个结构是同一个对象吗?
  2. 他们有相同的价值吗?

要找出它们是否是相同的对象,请比较指向两个结构的指针是否相等。 如果你想了解一般情况下是否具有相同的价值,你必须做深入的比较。 这包括比较所有的成员。 如果成员是指向其他结构的指针,则还需要将这些结构recursion到这些结构中。

在结构体不包含指针的特殊情况下,您可以使用memcmp对每个数据中的数据进行按位比较,而不必知道数据的含义。

确保你知道每个成员的“等于”意味着什么 – 对于整数值是显而易见的,但对于浮点值或用户定义的types则更为微妙。

如果2个结构variables是用calloc初始化的,或者它们是用memset设置为0,那么你可以比较你的2个结构和memcmp,不用担心结构垃圾,这样可以让你获得时间

此兼容示例使用Microsoft Visual Studio的#pragma pack编译器扩展来确保结构成员尽可能紧密地打包:

 #include <string.h> #pragma pack(push, 1) struct s { char c; int i; char buffer[13]; }; #pragma pack(pop) void compare(const struct s *left, const struct s *right) { if (0 == memcmp(left, right, sizeof(struct s))) { /* ... */ } }