我们如何比较C中相等的结构?

时间:2020-03-06 14:48:23  来源:igfitidea点击:

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

解决方案

C没有提供语言工具来做到这一点,我们必须自己做,并逐个成员比较每个结构。

如果我们做了很多,我建议我们编写一个比较这两种结构的函数。这样,如果我们更改结构,则只需要在一个位置更改比较即可。

至于如何做...。我们需要分别比较每个元素

我们可能会想使用memcmp(&a,&b,sizeof(struct foo)),但可能无法在所有情况下都起作用。编译器可以向结构中添加对齐缓冲区空间,并且不能保证在缓冲区空间中位于内存位置的值是任何特定值。

但是,如果在使用结构之前使用结构的全部大小使用calloc或者memset,则可以与memcmp进行浅表比较(如果结构包含指针,则仅当指针指向的地址匹配时才匹配)都一样)。

由于结构中字段之间可能存在随机填充字符,因此无法使用memcmp比较结构是否相等。

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

上面对于这样的结构将失败:

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

为了安全起见,我们必须使用逐成员比较。

如果结构仅包含基元,或者我们对严格相等感兴趣,则可以执行以下操作:

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

但是,如果结构包含指向其他结构或者联合的指针,那么我们将需要编写一个函数,该函数正确地比较基元,并在适当时针对其他结构进行比较调用。

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

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

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

这取决于我们要问的问题是:

  • 这两个结构是同一个对象吗?
  • 它们具有相同的价值吗?

要找出它们是否是同一对象,请比较两个结构的指针是否相等。
如果我们想大致了解它们是否具有相同的值,则必须进行深入比较。这涉及比较所有成员。如果成员是指向其他结构的指针,则也需要递归到这些结构。

在结构不包含指针的特殊情况下,我们可以执行memcmp来执行每个结构中包含的数据的按位比较,而不必知道数据的含义。

确保我们知道"等于"对于每个成员意味着什么,对于整数来说这是显而易见的,但对于浮点值或者用户定义的类型则更为微妙。