문제

너는 어떻게 비교하는 두 개의 인스턴스의 구조체에 대한 평등에서 C 표준?

도움이 되었습니까?

해결책

C는이 작업을 수행 할 언어 시설을 제공하지 않습니다. 직접 수행하고 각 구조 구성원을 구성원별로 비교해야합니다.

다른 팁

당신은 사용하고 싶은 유혹을받을 수 있습니다 memcmp(&a, &b, sizeof(struct foo)), 그러나 모든 상황에서는 작동하지 않을 수 있습니다. 컴파일러는 구조에 정렬 버퍼 공간을 추가 할 수 있으며, 버퍼 공간에있는 메모리 위치에서 발견 된 값은 특정 값으로 보장되지 않습니다.

그러나 사용하는 경우 calloc 또는 memset 구조물의 전체 크기를 사용하기 전에 ~할 수 있다 do a 얕은 비교 memcmp (구조에 포인터가 포함 된 경우 포인터가 가리키는 주소가 동일하다면 일치합니다).

만약 당신이 그것을 많이 쓰는 함수를 비교하는 두 개의 구조입니다.는 방법은,당신이 이제까지 구조를 변경할만을 변경할 필요가 비교에서 하나의 장소입니다.

는 방법에 관해 그것을 할 수 있습니다....당신은 필요를 비교하는 모든 요소가 개별적으로

structs의 필드 사이의 잠재적 임의의 패딩 문자로 인해 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

@그렉은 올바른 해야 한다는 명시적으로 작성 비교 함수에서 일반적인 경우입니다.

사용 가능 memcmp 경우:

  • 이는 구조체를 포함하지 않는 부동 소수점 필드에 있는 가능성 NaN.
  • 이는 구조체를 포함하지 않는 여백(사용 -Wpadded 로그램 이를 확인하려면)이나의 구조체 명시적으로 초기화됩 memset 에서 초기화.
  • 기원 형태(등과 같은 윈도우 BOOL 가)에 뚜렷만 해당하는 값입니다.

지 않는 한 당신은 당신을 위한 프로그래밍 임베디드 시스템(또는 작성하는 라이브러리를 사용할 수 있습니다 그들에게),나는 것에 대해 걱정하지 않는 일부의 사례에서 C 표준입니다.가까운 대멀리 포인터 차이에 존재하지 않는 모든 32 비트 또는 64 비트 장치입니다.Non-임베디드 시스템을 내가 알고 있는 여러 NULL 포인터입니다.

또 다른 옵션은 자동으로 생성 평등 기능입니다.는 경우에 당신이 당신의 구조체의 정의에서 간단한 방법으로 사용하는 것이 가능하는 단순한 텍스트 처리를 처리하는 간단한 구조체 정의입니다.당신이 사용할 수 있는된 형식으로 유지에 대한 일반적인 경우–사용하기 때문에 동일한 프로그램,처리하는 모든 모퉁이의 경우 올바로(없다면 버그).

나는 보지 못 같은 코드를 생성합니다.그러나,그것은 상대적으로 간단합니다.

그러나,그것은 또한 경우에는 그런 생성된 동등 기능을 것이 자주 틀리는 것에서 응용 프로그램 수준입니다.예를 들어,두 개가 UNICODE_STRING 구조체에서 윈도우 비교할 얕게 또는 깊은?

그것은 당신이 묻는 질문이 다음과 같은지에 달려 있습니다.

  1. 이 두 structs는 같은 물체입니까?
  2. 그들은 같은 가치를 가지고 있습니까?

그것들이 같은 대상인지 알아 보려면, 포인터를 평등을 위해 두 구조와 비교하십시오. 일반적으로 동일한 값이 있는지 알아 내려면 깊은 비교를해야합니다. 여기에는 모든 회원을 비교하는 것이 포함됩니다. 멤버가 다른 구조에 대한 포인터 인 경우 해당 구조로 되돌아 가야합니다.

structs에 포인터가 포함되어 있지 않은 특수한 경우 데이터의 의미를 알지 못하고 각각에 포함 된 데이터를 약간 비교하기 위해 MEMCMP를 수행 할 수 있습니다.

각 멤버에 대한 '평등'이 무엇을 의미하는지 알 수 있습니다. 부유 식 점 값이나 사용자 정의 유형에 있어서는 INT에게는 분명하지만 더 미묘합니다.

memcmp 구조를 비교하지 않고 memcmp 이진을 비교하고 구조물에는 항상 쓰레기가 있으므로 항상 허위로 나옵니다.

요소별로 금고를 비교하고 실패하지 않습니다.

스트러크에 프리미티브 만 포함되거나 엄격한 평등에 관심이있는 경우 다음과 같은 일을 할 수 있습니다.

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

그러나 Structs에 다른 스트러크 또는 노조에 대한 포인터가 포함 된 경우 프리미티브를 올바르게 비교하고 다른 구조를 적절하게 비교하는 기능을 작성해야합니다.

그러나 ADT 초기화의 일부로 구조물의 메모리 범위를 제로화하기 위해 memset (& a, sizeof (struct my_struct), 1)를 사용해야합니다.

2 개의 구조 변수가 Calloc으로 초기화되거나 Memset에 의해 0으로 설정되어 있으므로 두 구조를 MEMCMP와 비교할 수 있으며 구조 쓰레기에 대해 걱정할 수 없으며 시간을 벌 수 있습니다.

이 호환 예제는 Microsoft Visual Studio의 #Pragma Pack Compiler Extension을 사용하여 구조 멤버가 가능한 한 단단히 포장되도록합니다.

#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))) {
    /* ... */
  }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top