문제
너는 어떻게 비교하는 두 개의 인스턴스의 구조체에 대한 평등에서 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에 의해 정의됩니다.
@그렉은 올바른 해야 한다는 명시적으로 작성 비교 함수에서 일반적인 경우입니다.
사용 가능 memcmp
경우:
- 이는 구조체를 포함하지 않는 부동 소수점 필드에 있는 가능성
NaN
. - 이는 구조체를 포함하지 않는 여백(사용
-Wpadded
로그램 이를 확인하려면)이나의 구조체 명시적으로 초기화됩memset
에서 초기화. - 기원 형태(등과 같은 윈도우
BOOL
가)에 뚜렷만 해당하는 값입니다.
지 않는 한 당신은 당신을 위한 프로그래밍 임베디드 시스템(또는 작성하는 라이브러리를 사용할 수 있습니다 그들에게),나는 것에 대해 걱정하지 않는 일부의 사례에서 C 표준입니다.가까운 대멀리 포인터 차이에 존재하지 않는 모든 32 비트 또는 64 비트 장치입니다.Non-임베디드 시스템을 내가 알고 있는 여러 NULL
포인터입니다.
또 다른 옵션은 자동으로 생성 평등 기능입니다.는 경우에 당신이 당신의 구조체의 정의에서 간단한 방법으로 사용하는 것이 가능하는 단순한 텍스트 처리를 처리하는 간단한 구조체 정의입니다.당신이 사용할 수 있는된 형식으로 유지에 대한 일반적인 경우–사용하기 때문에 동일한 프로그램,처리하는 모든 모퉁이의 경우 올바로(없다면 버그).
나는 보지 못 같은 코드를 생성합니다.그러나,그것은 상대적으로 간단합니다.
그러나,그것은 또한 경우에는 그런 생성된 동등 기능을 것이 자주 틀리는 것에서 응용 프로그램 수준입니다.예를 들어,두 개가 UNICODE_STRING
구조체에서 윈도우 비교할 얕게 또는 깊은?
그것은 당신이 묻는 질문이 다음과 같은지에 달려 있습니다.
- 이 두 structs는 같은 물체입니까?
- 그들은 같은 가치를 가지고 있습니까?
그것들이 같은 대상인지 알아 보려면, 포인터를 평등을 위해 두 구조와 비교하십시오. 일반적으로 동일한 값이 있는지 알아 내려면 깊은 비교를해야합니다. 여기에는 모든 회원을 비교하는 것이 포함됩니다. 멤버가 다른 구조에 대한 포인터 인 경우 해당 구조로 되돌아 가야합니다.
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))) {
/* ... */
}
}