티스토리 뷰

프로그래밍/알고리즘

qsort()에 대한 글

터프 프로그래머 2011. 2. 25. 21:30

/*

0. 함수 포인터(변수)가 무엇 ?

포인터에 대해서 처음 배울 때 데이타에 대한 포인터를 배우고  주로 이들 포인터에

대하여만 다루어왔기 때문에 아마도 함수 포인터에 대해서는 낮설을 수 있다고

생각합니다.

 

일단 포인터라는 것은 메모리의 어떤 위치를 가르키는 주소라는 것에 유념한다면

함수에 대한 포인터도 낯설 것이 없다고 봅니다.

 

데이타에 대한 포인터는 데이타들이 위치하는 메모리의 데이타 영역에 대한 주소이고

함수에 대한 포인터는 함수의 코드가 위치하는 메모리의 코드 영역에 대한 주소라고

볼 수 있습니다.

 

포인터 변수는 이러한 포인터를 저장하는 변수라고 볼 수 있습니다.

주소라는 것이 실제로 정수이므로 정수데이타 형과 구분하기 위하여

*라는 것을 데이타형의 뒤에 덧붙입니다.

 

마찬 가지로 정수형 데이탸에 대한 포인터와

함수에 대한 포인터와 구별하기 위하여

함수형에 대한 포인터라는 것이 필요하다고 볼 수 있습니다. 

 

1.1. 

데이타 포인터 변수의 선언과 할당(대입)

데이타에 대한 포인터는  T가 데이타 형이라면

T* pdata; 와 같은 형식으로 선언됩니다..

 

즉 데이타형 T 뒤에 *를 덧 붙입니다.

그리고 할당(대입)할 때는 선언된 어떤 데이타 

T d; 에 대하여

pdata = &d; 와 같이 실재로 존재하는 d라는 T형의 변수를 가르키도록

할당할 수 있습니다..

이렇게 하므로서 포인터 변수에 어떤 데이타가 위치하는 메모리상의 번지수를

저장할 수 있습니다.

 

1.2.

함수 포인터  변수의 선언과 할당(대입)

마찬가지로 데이타의 형이 있는 것과 같이 함수에도 형이 있습니다.

보통 프로토 타입(prototype)이라고 부르기도 하는 데

리턴 타입과  파라메타 리스트의 파라메타 갯수와 그 타입들이 정의되는 규격을

함수의 형이라고 부릅니다.

 

데이타의 포인터가 데이타형과 관련되어 표기되는 것과 같이

함수에 대한 포인터도 함수의 형과 관련하여 표기됩니다. ( T1과 T2가 데이타 형이라면)

T  (*pfunc ) ( T1, T2 );  

 

즉 함수의 원형(프로토타입) T (T1,T2) 에서 (*)를 덧 붙여서 표기합니다.

주의 할것은 여기서 pfunc은 함수를 가르키는 포인터 변수라는 것입니다.

 

그래서 데이타에서의 포인터 변수와 같이 어떤 선언된 함수를 가르키도록

할당(대입)할 수 있다는 것입니다. 아래와 같은 형의  함수가 선언되어 있고

그 함수에 대한 정의가 존재한다면

T func( T1 t1, T2 t2 );  와 같이 선언된 함수를 포인트하려면

 

pfunc = func;( &func과 func은 같은 결과(주소)를 얻습니다. )과

같이 표기할 수가 있습니다.

이렇게 할당하면

pfunc는 func이라는 함수의  코드가 위치하는 코드영역의 시작 주소를 나타내게 됩니다.

 

3. 함수포인터는 어디에 쓰이는가?

함수의 파라메타로 데이타형에 포인터를 전달할 수있는 것과 같이

함수에 대한 포인터도 파라메타로 전달될 수 있습니다.

 

qsort라는 함수는 함수에 대한 포인터 변수 compare를 마지막 파라메타로

취하고 있습니다.

 

파라메타 compare라는 포인트  변수는

리턴형이 int이고 두개의 파라메타의 형이 const void*인 함수 즉

int (const void*, cons void* )와 같은 형식으로 선언되는 함수들에 대한  포인터를

저장하는 변수입니다.

 

qsort가 비교함수에 대한 포인터를 파라메타로 취한다는 것은

qsort라는 함수 내부에서 이 비교함수를 실행하겠다는 뜻으로 볼 수 있습니다.

말 할 것도 없이 그 비교함수는 qsort의 내부에서 정렬시에 두 데이타들을 비교하기

위하여 사용되는 함수라고 볼 수 있겠죠.

 

그러한 함수는 리턴형과 파라메타만이  정의되어 있을 뿐  구체적으로 

어느 함수인지는 확정되지 아니한 상태입니다.

 

그러므로 qsort를 호출할 때에 미리정의된 라이브러리의 함수를 이용하기 위하여

헤더화일의 비교함수를 인수로 전달할 수도 있고 아니면 사용자가

그 함수의 형( 리턴 타입과 파라메타 리스트의 수와 형 )에 맞는 새로운 비교함수를

정의하고 그 함수이름(포인터)을 전달할 수도 있을 것입니다.

 

아래는 사용자가 정의한 sort_functionqsort의 마지막 파라메타로 전달하여

list라는 배열의 단어들을 정렬하고 그 결과를 출력하는 예입니다..

*/

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int sort_function( const void *a, const void *b);

 

char list[5][4] = { "cat", "car", "cab", "cap", "can" };

int main(void)
{
   int  x;

  

   /* 함수 포인터 변수 comp의 선언  */

   int (*comp)(const void*, const void* );

 

   /*

   comp 포인터 변수를 실제 존재하는 함수 sort_function으로 대입하고

   comp를 qsort함수의 파라메타로 전달합니다. */

 

   comp = sort_function;

   qsort((void *)list, 5, sizeof(list[0]), comp );


   for (x = 0; x < 5; x++)
      printf("%s\n", list[x]);
   return 0;
}

 

int sort_function( const void *a, const void *b)
{
   return( strcmp((char *)a,(char *)b) );
}




**출처**

 http://kin.naver.com/qna/detail.nhn?d1id=1&dirId=1040101&docId=69208296&qb=cXNvcnQoKQ==&enc=utf8&section=kin&rank=5&sort=0&spq=0&pid=f2v1xv331y8ssbv3hxZssv--122887&sid=S2D0e-HFYEsAAFVrb8I

'프로그래밍 > 알고리즘' 카테고리의 다른 글

기말 고사 준비(기업투자)  (0) 2011.02.25
섬의 침몰 - 플로이드필 문제  (0) 2011.02.25
음식고르기  (0) 2011.02.25
정삼각형 만들기  (0) 2011.02.25
높은 탑 쌓기  (0) 2011.02.25
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday