memcmpDeclaration int memcmp( const void *buf1, const void *buf2, size_t count ) |
Return value 성공 - buf1이 크면 양수, 작으면 음수, 같으면 0 반환 실패 - 없음
Parameters buf1 - 비교할 첫 번째 메모리 buf2 - 비교할 두 번째 메모리 count - 비교할 문자 개수
Detail descriptionsmemcmp()는 메모리를 비교합니다. 모든 자료형에 대해 동작하도록 만들었기 때문에 비교 단위는 바이트가 됩니다. 간혹 memcmp()와 같은 비교 함수들의 반환값을 참 또는 거짓이라고 생각하는 사람들이 있습니다. 이러한 사람들은 원하는 것을 정확하게 찾길 바라는 공통점이 있습니다. 이름이나 주소를 찾을 때 완전히 일치하기를 바랍니다. 그러나, 실제 상황에서는 똑같은 것을 찾는 것도 중요하지만, 크거나 작은 데이터를 찾는 것도 중요합니다. 그래서, memcmp()와 같은 비교 함수들은 세 가지(>, <, ==) 결과를 반환합니다. "크다(>)"와 "작다(<)"를 알 수 있으면 데이터를 순서대로 배치할 수 있습니다. 이와 같은 작업을 자료 구조에서는 정렬(sort)이라고 부릅니다. 충분한 설명을 하지는 못하지만, 정렬 때문에 memcmp()는 세 가지 값을 반환할 수밖에 없습니다. buf1이 buf2가 가리키는 값보다 클 때는 0보다 큰 값, 다시 말해 양수를 반환하고, buf1이 buf2가 가리키는 값보다 작을 때는 0보다 작은 값, 음수를 반환합니다. buf1과 buf2가 가리키는 값이 같을 때는 0을 반환합니다. 참과 거짓으로 따진다면, 같을 때 거짓을 반환하는 셈이 되므로 주의가 필요합니다. 같은 것을 찾는 코드는 이곳의 "Example codes" 항목에 있고, 문자열 배열을 정렬하기 위해 큰 것을 찾는 코드는 strcmp()에 있습니다. memcmp()는 문자열을 제외한 모든 비교에서 사용합니다. 문자열 비교는 전담 함수인 strcmp()로 처리하지만, 그외의 모든 경우에는 memcmp()로 처리합니다. 대표적으로 배열과 구조체 비교에 사용합니다. 두 개의 배열이 있을 때 같은 요소로 채워져 있는지 검사한다던가 구조체 멤버의 내용이 같은지 검사할 때 주로 사용합니다. 그러나, 배열 요소나 구조체 멤버 중에 포인터(주소)가 있다면 memcmp()를 사용할 수 없습니다. memcmp()를 사용하는 목적은 데이터가 같은지 비교하는데 있습니다. 주소가 같은지 비교하는 것이 아닙니다. 제대로 된 비교라면, 주소가 가리키는 곳의 데이터를 비교할 수 있어야 하는데 memcmp()로는 할 수 없는 작업입니다. 주의하기 바랍니다. 참고로 문자열이 배열의 형태로 존재해도 안됩니다. null 문자 뒤에는 쓰레기가 있는데, memcmp()는 이들 쓰레기까지 같은지 검사하기 때문에 정확하게 동작하지 않습니다.
Remarks 다음은 비교 함수로 사용되어지는 몇 가지 함수들을 비교한 표입니다. 이름 | 설명 | 종료 | 반환 | memcmp | 메모리 비교 | 지정 개수만큼 비교하면 | 양수, 0, 음수 | strcmp | 문자열 비교 | null 문자를 만나면 | 양수, 0, 음수 | strncmp | 문자열 비교 | 지정 개수만큼 비교하거나 null 문자를 만나면 | 양수, 0, 음수 |
Header files <string.h> <memory.h>
Example codes- memcmp()를 사용해서 배열에 들어있는 요소들이 같은지 비교합니다.
- "같다"와 "다르다"라는 결과를 모두 만들기 위해 크기가 10인 배열(p1)을 처음부터 5개만 다른 배열(p2)에 복사합니다.
- 첫 번째 memcmp() 호출은 10개의 요소가 모두 같은지 비교합니다. 5개만 복사했으므로 같지 않기 때문에 memcmp()는 0이 아닌 값을 반환합니다. memcmp()는 같은 경우에만 0을 반환합니다.
- 두 번째 memcmp() 호출은 복사해 놓은 5개의 요소만 비교합니다. 호출 결과는 0이 되고 "같다"라고 출력됩니다.
- memcmp()나 memcpy() 등의 메모리 관련 함수를 사용할 때는 반드시 sizeof 연산자와 함께 사용합니다. 단위가 바이트이기 때문에 지금처럼 int 자료형이라면 4를 곱해야 처리하고자 하는 메모리 크기를 얻을 수 있습니다.
#include <stdio.h> #include <string.h>
void main() { int p1[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; int p2[10];
memcpy( p2, p1, 5*sizeof(p1[0]) );
if( memcmp(p1, p2, 10*sizeof(p1[0])) == 0 ) printf( "10개 : 같다\n" ); else printf( "10개 : 다르다\n" );
if( memcmp(p1, p2, 5 *sizeof(p1[0])) == 0 ) printf( " 5개 : 같다\n" ); else printf( " 5개 : 다르다\n" ); }
[출력 결과] 10개 : 다르다 5개 : 같다
|
- 좌표를 저장한 POINT 구조체 배열에서 memcmp()를 이용해서 좌표를 검색합니다.
- 여기서는 구조체 멤버가 단순하기 때문에 직접 비교하는 "array[i].x == point->x && array[i].y == point->y"를 사용해도 됩니다. 그러나, 구조체 멤버가 많아지면 memcmp()를 사용하는 것이 편하다는 것을 알게될 것입니다.
- 먼저 좌표를 5개 입력받고, 올바르게 입력받았는지 화면에 출력합니다. 그런 다음 검색할 좌표를 별도로 입력받습니다. 그리고, FindPoints()를 호출해서 찾고자 하는 좌표가 있는지 검사합니다.
- FindPoints()는 있다면 몇 번째에 있는지 알려주고, 없다면 -1을 반환합니다. 출력 결과에서는 3번째에 있다고 알려줍니다. 배열 인덱스는 0부터 시작하므로 맞는 결과입니다.
#include <stdio.h> #include <string.h>
struct POINT { int x, y; };
void ScanPoints( struct POINT* array, int size ); void ShowPoints( struct POINT* array, int size ); int FindPoints( struct POINT* array, int size, struct POINT* point );
void main() { struct POINT array[5], pt; int find;
ScanPoints( array, 5 ); ShowPoints( array, 5 );
printf( "검색 : " ); scanf( "%d %d", &pt.x, &pt.y );
find = FindPoints( array, 5, &pt );
if( find < 0 ) printf( "결과 : 없음\n" ); else printf( "결과 : 성공[%d번째]\n", find ); }
void ScanPoints( struct POINT* array, int size ) { int i; printf( "[입력]\n" );
for( i = 0; i < size; i++ ) { printf( "%d : ", i ); scanf( "%d %d", &array[i].x, &array[i].y ); } }
void ShowPoints( struct POINT* array, int size ) { int i; printf( "[출력]\n" );
for( i = 0; i < size; i++ ) printf( "[%d, %d] ", array[i].x, array[i].y );
printf( "\n" ); }
int FindPoints( struct POINT* array, int size, struct POINT* point ) { int i; for( i = 0; i < size; i++ ) { if( memcmp(&array[i], point, sizeof(struct POINT)) == 0 ) return i; }
return -1; }
[출력 결과] [입력] 0 : 90 20 1 : 80 30 2 : 70 40 3 : 60 50 4 : 40 50 [출력] [90, 20] [80, 30] [70, 40] [60, 50] [40, 50] 검색 : 60 50 결과 : 성공[3번째]
|
이 문서에 대한 모든 권리는 www.printf.co.kr에 있습니다. [최종 수정일: 2006.12.30.] |