你如何比较在C平等结构?(How do you compare structs for equali

2019-07-17 20:53发布

你如何比较结构的两个实例在标准C平等?

Answer 1:

C提供无语言设施来做到这一点 - 你必须做你自己,并通过成员的每个结构成员进行比较。



Answer 2:

你可能会使用memcmp(&a, &b, sizeof(struct foo))但它可能不会在所有情况下工作。 编译器可以添加对齐缓冲器空间的结构,并且在位于在缓冲空间的存储器位置中的值是不保证任何特定值。

但是,如果你使用callocmemset使用之前的结构的全尺寸,你可以做一个浅层比较memcmp (如果您的结构中包含指针,它只会如果地址指针都指向是相同的匹配)。



Answer 3:

如果你这样做了很多,我建议写两个结构比较的功能。 这样,如果你改变你只需要改变结构比较在同一个地方。

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



Answer 4:

不能使用memcmp比较平等结构,由于在结构领域之间的潜在随机填充字符。

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

上面会失败这样的结构:

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

你必须使用成员两比较是安全的。



Answer 5:

请注意,您可以使用memcmp()对非静态钢结构制品,而不必担心填充,只要你不初始化所有成员(一次)。 这是由C90定义:

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



Answer 6:

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

它可以使用memcmp如果:

  • 该结构不包含那些可能浮点领域NaN
  • 该结构包含无边框(使用-Wpadded铿锵检查本)或结构被明确初始化所用memset在初始化。
  • 没有成员类型(如Windows BOOL ),其具有不同的但等效的值。

除非你是编程的嵌入式系统(或写,可能对他们使用的库),我就不会担心一些极端案例中的C标准。 近远与指针的区别不任何32位或64位设备上存在。 没有非嵌入式系统,我知道有多个NULL指针。

另一种选择是自动生成的平等功能。 如果你躺在你的结构定义了一个简单的方法,可以用简单的文本处理来处理简单的结构定义。 您可以使用libclang对于一般情况 - 因为它使用相同的前端,铛,它正确地处理所有的情况(除非错误)。

我还没有看到这样的代码生成库。 然而,这似乎比较简单。

然而,它也是这样产生的平等功能会经常做错误的事情,在应用层面的情况。 例如,应在2层UNICODE_STRING在Windows结构进行浅或深相比?



Answer 7:

这要看你问的问题是:

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

要看看他们是同一个对象,比较指针指向两个结构是否相等。 如果您想了解一般的,如果它们具有相同的价值,你必须做深刻的对比。 这涉及到所有成员进行比较。 如果成员是指向其他结构需要递归到这些结构了。

在特殊情况下的结构不包含指针,你可以做一个memcmp执行包含在每个数据的逐位比较,而不需要知道数据的含义。

确保你知道什么是“等于”是指每个成员 - 这是显而易见的整数,但更微妙的,当涉及到浮点值或用户定义类型。



Answer 8:

memcmp不比较结构, memcmp比较二进制文件,总有垃圾的结构,因此它永远是假的比较。

通过元素其安全比较元素,不会失败。



Answer 9:

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

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

但是,如果你的结构包含指向其他结构或联合,那么你将需要编写一个基元比较正常的功能,使对其他结构适当的比较调用。

请注意,但是,你应该使用memset的(一,的sizeof(结构my_struct),1),以零出结构的内存范围内的ADT初始化的一部分。



Answer 10:

如果两个变量的结构是initialied用calloc或者正在memset的设定为0,所以你可以用memcmp比较你2层结构和没有关于结构垃圾担心,这将让你赢得时间



Answer 11:

该标准的示例使用Microsoft Visual Studio中的#pragma包编译器扩展,以确保成员都挤满尽可能紧的结构:

#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))) {
    /* ... */
  }
}


文章来源: How do you compare structs for equality in C?