posted by 구름너머 2008. 8. 17. 21:08
[본문스크랩] memcmp | 나의 관심정보 메모 삭제 2008/08/17 21:07
damool2 http://memolog.blog.naver.com/damool2/113
출처 카페 > 김샘과 함께 하는 C 언어 | 사과쿵
원본 http://cafe.naver.com/applekoong/160

memcmp

메모리를 비교합니다.

Declaration

int memcmp( const void *buf1, const void *buf2, size_t count )

Return value

성공 - buf1이 크면 양수, 작으면 음수, 같으면 0 반환
실패 - 없음


Parameters

buf1 - 비교할 첫 번째 메모리
buf2 - 비교할 두 번째 메모리
count - 비교할 문자 개수


Detail descriptions

memcmp()는 메모리를 비교합니다. 모든 자료형에 대해 동작하도록 만들었기 때문에 비교 단위는 바이트가 됩니다. 간혹 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

  1. memcmp()를 사용해서 배열에 들어있는 요소들이 같은지 비교합니다.
  2. "같다"와 "다르다"라는 결과를 모두 만들기 위해 크기가 10인 배열(p1)을 처음부터 5개만 다른 배열(p2)에 복사합니다.
  3. 첫 번째 memcmp() 호출은 10개의 요소가 모두 같은지 비교합니다. 5개만 복사했으므로 같지 않기 때문에 memcmp()는 0이 아닌 값을 반환합니다. memcmp()는 같은 경우에만 0을 반환합니다.
  4. 두 번째 memcmp() 호출은 복사해 놓은 5개의 요소만 비교합니다. 호출 결과는 0이 되고 "같다"라고 출력됩니다.
  5. 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개 : 같다


  1. 좌표를 저장한 POINT 구조체 배열에서 memcmp()를 이용해서 좌표를 검색합니다.
  2. 여기서는 구조체 멤버가 단순하기 때문에 직접 비교하는 "array[i].x == point->x && array[i].y == point->y"를 사용해도 됩니다. 그러나, 구조체 멤버가 많아지면 memcmp()를 사용하는 것이 편하다는 것을 알게될 것입니다.
  3. 먼저 좌표를 5개 입력받고, 올바르게 입력받았는지 화면에 출력합니다. 그런 다음 검색할 좌표를 별도로 입력받습니다. 그리고, FindPoints()를 호출해서 찾고자 하는 좌표가 있는지 검사합니다.
  4. 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.]

'UNIX' 카테고리의 다른 글

head와 tail의 만남  (0) 2008.09.03
Message Queues 조회 및 삭제  (0) 2008.09.03
S_ISREG()  (0) 2008.07.16
cvs에 대해 잘 정리된 곳..  (0) 2008.03.05
유닉스 파일 문자열 바꾸기  (0) 2008.02.25