How do you compare structs for equality in C?

2019-01-02 17:11发布

How do you compare two instances of structs for equality in standard C?

11条回答
查无此人
2楼-- · 2019-01-02 17:51

If the structs only contain primitives or if you are interested in strict equality then you can do something like this:

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

However, if your structs contain pointers to other structs or unions then you will need to write a function that compares the primitives properly and make comparison calls against the other structures as appropriate.

Be aware, however, that you should have used memset(&a, sizeof(struct my_struct), 1) to zero out the memory range of the structures as part of your ADT initialization.

查看更多
萌妹纸的霸气范
3楼-- · 2019-01-02 17:54

You may be tempted to use memcmp(&a, &b, sizeof(struct foo)), but it may not work in all situations. The compiler may add alignment buffer space to a structure, and the values found at memory locations lying in the buffer space are not guaranteed to be any particular value.

But, if you use calloc or memset the full size of the structures before using them, you can do a shallow comparison with memcmp (if your structure contains pointers, it will match only if the address the pointers are pointing to are the same).

查看更多
旧时光的记忆
4楼-- · 2019-01-02 18:00

This compliant example uses the #pragma pack compiler extension from Microsoft Visual Studio to ensure the structure members are packed as tightly as possible:

#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))) {
    /* ... */
  }
}
查看更多
君临天下
5楼-- · 2019-01-02 18:01

You can't use memcmp to compare structs for equality due to potential random padding characters between field in structs.

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

The above would fail for a struct like this:

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

You have to use member-wise comparison to be safe.

查看更多
明月照影归
6楼-- · 2019-01-02 18:04

It depends on whether the question you are asking is:

  1. Are these two structs the same object?
  2. Do they have the same value?

To find out if they are the same object, compare pointers to the two structs for equality. If you want to find out in general if they have the same value you have to do a deep comparison. This involves comparing all the members. If the members are pointers to other structs you need to recurse into those structs too.

In the special case where the structs do not contain pointers you can do a memcmp to perform a bitwise comparison of the data contained in each without having to know what the data means.

Make sure you know what 'equals' means for each member - it is obvious for ints but more subtle when it comes to floating-point values or user-defined types.

查看更多
冷夜・残月
7楼-- · 2019-01-02 18:07

if the 2 structures variable are initialied with calloc or they are set with 0 by memset so you can compare your 2 structures with memcmp and there is no worry about structure garbage and this will allow you to earn time

查看更多
登录 后发表回答