Programing

C에서 평등에 대한 구조체를 어떻게 비교합니까?

lottogame 2020. 5. 10. 10:14
반응형

C에서 평등에 대한 구조체를 어떻게 비교합니까?


표준 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 ;

안전을 위해 멤버 별 비교를 사용해야합니다.


@Greg는 일반적인 경우 명시적인 비교 함수를 작성해야합니다.

다음과 같은 memcmp경우 에 사용할 수 있습니다.

  • 구조체에는 가능한 부동 소수점 필드가 없습니다 NaN.
  • 구조체에 패딩이 포함되어 있지 않거나 ( -Wpaddedclang을 사용 하여이를 확인) 구조체를 초기화 할 memset명시 적으로 초기화합니다.
  • BOOL고유하지만 동등한 값을 갖는 멤버 유형 (예 : Windows )이 없습니다.

임베디드 시스템을 프로그래밍하거나 (또는 ​​그에 사용될 라이브러리를 작성하지 않는 한) C 표준의 일부 경우에 대해 걱정하지 않을 것입니다. 32 비트 또는 64 비트 장치에는 근거리 포인터와 원거리 포인터 구별이 없습니다. 내가 아는 내장형 시스템에는 여러 개의 NULL포인터가 없습니다.

다른 옵션은 등식 함수를 자동 생성하는 것입니다. 구조체 정의를 간단한 방법으로 배치하면 간단한 텍스트 처리를 사용하여 간단한 구조체 정의를 처리 할 수 ​​있습니다. 일반적인 경우에 libclang을 사용할 수 있습니다. Clang과 동일한 프런트 엔드를 사용하기 때문에 모든 코너 경우를 올바르게 처리합니다 (버그 제외).

그런 코드 생성 라이브러리를 보지 못했습니다. 그러나 비교적 단순 해 보입니다.

그러나 이와 같이 생성 된 등식 함수가 종종 응용 프로그램 레벨에서 잘못된 일을하는 경우도 있습니다. 예를 들어, UNICODE_STRINGWindows에서 두 개의 구조체를 얕게 또는 깊게 비교 해야 합니까?


모든 멤버를 한 번에 초기화하지 않는 한 패딩에 대해 걱정하지 않고 정적이 아닌 구조에서 memcmp ()를 사용할 수 있습니다. 이것은 C90에 의해 정의됩니다.

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


묻는 질문에 따라 다릅니다.

  1. 이 두 구조체가 같은 객체입니까?
  2. 그들은 같은 가치가 있습니까?

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.


memcmp does not compare structure, memcmp compares the binary, and there is always garbage in the struct, therefore it always comes out False in comparison.

Compare element by element its safe and doesn't fail.


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.


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


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

참고URL : https://stackoverflow.com/questions/141720/how-do-you-compare-structs-for-equality-in-c

반응형