기본 패턴
c
int compare_ints(const void *left, const void *right) {
int a = *(const int *)left;
int b = *(const int *)right;
return (a > b) - (a < b);
}
qsort(values, count, sizeof(int), compare_ints);설명
qsort와bsearch는 "어떤 타입 배열이든 비교 함수만 주면 처리할 수 있다"는 식으로 설계된 표준 라이브러리 함수입니다. C의 일반화 스타일을 잘 보여 주는 예입니다.qsort는 배열을 정렬하고,bsearch는 정렬된 배열에서 이진 검색을 수행합니다. 둘 다 원소 타입을 모르기 때문에void *와 원소 크기, 비교 함수에 의존합니다.- 비교 함수가 이 카드의 핵심입니다. 두 원소를 어떤 기준으로 비교할지 사람이 정의해야 하며, 그 규칙이 일관되어야 정렬과 검색이 제대로 동작합니다.
- 이 패턴은 강력하지만 읽기 난이도도 있습니다. 특히
const void *를 실제 타입 포인터로 캐스팅하는 순간, "이 배열이 정말 그 타입 원소로 이루어졌는가"를 코드 작성자가 정확히 알아야 합니다. - 대학 교재 수준에서는 이 주제가 "C가 제네릭 없이 일반성을 어떻게 구현하는가"를 보여 주는 좋은 예입니다. type safety를 덜 얻는 대신, 함수 포인터와 raw memory 규약으로 일반화를 만든다고 볼 수 있습니다.
빠른 정리
| 요소 | 역할 |
|---|---|
qsort | 배열 정렬 |
bsearch | 정렬된 배열에서 이진 검색 |
| 비교 함수 | 두 원소의 순서 판단 |
void * | 타입 일반화를 위한 포인터 |
sizeof(T) | 원소 크기 전달 |
주의할 점
bsearch는 정렬되지 않은 배열에 쓰면 의미가 없습니다. 또한 정렬에 사용한 비교 기준과 검색 기준이 다르면
결과가 맞지 않을 수 있으므로, 두 함수는 같은 비교 규약을 공유하는 편이 중요합니다.
참고 링크
2 sources