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
. - 구조에는 패딩이 되어 있지 (「사용」을 사용).
-Wpadded
하기 위해을 사용하여) 으로 clang으로 됩니다.memset
를 참조해 주세요. - 멤버 타입은 없습니다(Windows 등).
BOOL
는, 각각 이지만, 한 값을 있습니다는 다른 값을 가지고 있지만 동등한 값을 가지고 있습니다.
임베디드 시스템용 프로그래밍(또는 시스템에서 사용할 수 있는 라이브러리를 작성하는 경우)이 아니라면 C 규격의 일부 코너 케이스에 대해서는 걱정하지 않습니다.32비트 또는 64비트 디바이스에서는 근접 포인터와 원 포인터의 구별이 존재하지 않습니다. 한 개의 .NULL
포인터
또 다른 옵션은 등식 함수를 자동 생성하는 것입니다.구조 정의를 단순하게 배치하는 경우 단순 텍스트 처리를 사용하여 단순 구조 정의를 처리할 수 있습니다.libclang은 일반적인 케이스에 사용할 수 있습니다.Clang과 같은 프런트 엔드를 사용하기 때문에 모든 코너 케이스가 올바르게 처리됩니다(버그 제외).
나는 그런 코드 생성 라이브러리를 본 적이 없다.하지만, 이것은 비교적 단순해 보입니다.
그러나 그러한 생성된 평등 함수가 애플리케이션 수준에서 종종 잘못된 일을 하는 경우도 있다.예를 들어, 두 개가UNICODE_STRING
Windows 의 구조를 얄팍하게 비교하거나 깊이 비교하거나 할 수 있습니까?
(한 번에) 모든 멤버를 초기화하지 않는 한 패딩을 걱정하지 않고 비 스태틱 구조에서 memcmp()를 사용할 수 있습니다.이것은 C90에 의해 정의됩니다.
http://www.pixelbeat.org/programming/gcc/auto_init.html
질문 내용이 다음과 같은지에 따라 달라집니다.
- 이 두 구조물은 같은 물체입니까?
- 같은 값인가요?
같은 오브젝트인지 아닌지를 확인하려면 두 구조물에 대한 포인터를 비교하여 동등함을 확인합니다.일반적으로 값이 동일한지 여부를 확인하려면 자세히 비교해야 합니다.이것은 모든 멤버들을 비교하는 것이다.구성원이 다른 구조물에 대한 포인터인 경우 해당 구조물에 다시 삽입해야 합니다.
구조에 포인터가 포함되어 있지 않은 특별한 경우 memcmp를 실행하여 데이터가 무엇을 의미하는지 알 필요 없이 각각에 포함된 데이터의 비트 비교를 수행할 수 있습니다.
각 멤버에 대해 '동등'이 무엇을 의미하는지 확인합니다.ints에는 분명하지만 부동 소수점 값이나 사용자 정의 유형에 대해서는 더 미묘합니다.
memcmp
구조를 비교하지 않습니다.memcmp
는 바이너리를 비교하고 구조체에는 항상 가비지가 존재하기 때문에 항상 False가 됩니다.
요소를 요소별로 비교하면 안전하며 실패하지 않습니다.
구조체에 기본 요소만 포함되거나 완전한 평등에 관심이 있는 경우 다음과 같은 작업을 수행할 수 있습니다.
int my_syslog_cmp(const structure my_syslog* lhs, const structure my_syslog* rhs){return memcmp(lhs, rsh, size of(my_syslogs));}
단, 구조에 다른 구조 또는 결합에 대한 포인터가 포함되어 있는 경우에는 원소를 적절히 비교하는 함수를 작성하고 필요에 따라 다른 구조와의 비교 호출을 해야 합니다.
단, ADT 초기화의 일부로서 memset(&a, sizeof(structure my_struct), 1)을 사용하여 구조의 메모리 범위를 제로화해야 합니다.
2개의 구조 변수가 calloc으로 초기화되거나 memset에 의해0 으로 설정되어 있는 경우, 2개의 구조를 memcmp와 비교할 수 있으며 구조 가비지에 대한 걱정이 없어 시간을 벌 수 있습니다.
이 준거 예에서는 Microsoft Visual Studio의 #pragma pack 컴파일러 확장을 사용하여 구조 멤버가 가능한 한 단단히 채워져 있는지 확인합니다.
#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
'programing' 카테고리의 다른 글
Javascript 변수 유형을 얻는 더 좋은 방법? (0) | 2022.10.23 |
---|---|
문자열로 표시되도록 전달된 JSON 열 - Larabel - Vuejs2 (0) | 2022.10.23 |
숫자의 소수점 이하/정수 여부를 확인합니다. (0) | 2022.10.23 |
오류: 테이블 " "에 대해 사용자 "@"에 대해 명령 거부됨 (0) | 2022.10.23 |
플라스크에 http 헤더를 넣는 방법 (0) | 2022.10.23 |