qsort() 함수란?
C 언어에서는 stdlib.h 헤더 파일을 통해 qsort() 함수를 제공합니다. 이 함수는 퀵 정렬(quicksort) 알고리즘을 기반으로 배열을 정렬하며, 정수 배열은 물론 구조체 배열 등 어떤 타입의 배열이든 정렬할 수 있도록 범용적으로 설계되었습니다.
qsort()를 사용하려면 반드시 비교 함수(comparator)를 함께 전달해야 합니다. 비교 함수는 두 개의 인자를 받아 두 요소 사이의 상대적인 순서를 판단하는 역할을 합니다. 이때 두 인자는 모두 포인터이며, const void* 타입으로 형 변환되어 전달됩니다. 함수 원형은 다음과 같습니다.
int comparator(const void* p1, const void* p2);반환값의 세 가지 의미
- 0보다 작은 값: p1이 가리키는 요소가 두 번째 요소보다 앞에 위치합니다.
- 0과 같은 값: 두 요소의 값이 동일하며 순서가 유지됩니다.
- 0보다 큰 값: p1이 가리키는 요소가 두 번째 요소보다 뒤에 위치합니다.
예제 코드
다음은 책 정보를 담은 구조체 배열을 가격(price) 기준으로 오름차순 정렬하는 예제입니다. 참고로 qsort()의 비교 함수는 반드시 const void* 포인터를 받아야 하므로, 함수 내부에서 구조체 포인터로 형 변환하여 사용하는 것이 올바른 방식입니다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char title[50];
int pages;
float price;
} book;
/* qsort()와 호환되는 비교 함수 */
int compareBook(const void* p1, const void* p2) {
const book* b1 = (const book*)p1;
const book* b2 = (const book*)p2;
if (b1->price < b2->price)
return -1; /* b1이 앞에 위치 */
else if (b1->price > b2->price)
return 1; /* b1이 뒤에 위치 */
return 0; /* 두 값이 같음 */
}
int main() {
int i;
book book_arr[5];
strcpy(book_arr[0].title, "C Programming");
book_arr[0].pages = 260;
book_arr[0].price = 450;
strcpy(book_arr[1].title, "DBMS Guide");
book_arr[1].pages = 850;
book_arr[1].price = 775;
strcpy(book_arr[2].title, "Learn C++");
book_arr[2].pages = 350;
book_arr[2].price = 520;
strcpy(book_arr[3].title, "Data Structures");
book_arr[3].pages = 380;
book_arr[3].price = 430;
strcpy(book_arr[4].title, "Learn Python");
book_arr[4].pages = 500;
book_arr[4].price = 300;
/* 배열 포인터, 요소 개수, 요소 크기, 비교 함수 순서로 전달 */
qsort((void*)book_arr, 5, sizeof(book_arr[0]), compareBook);
for (i = 0; i < 5; i++) {
printf("%-20s %5d %10.2f\n", book_arr[i].title, book_arr[i].pages, book_arr[i].price);
}
return 0;
}실행 결과
Learn Python 500 300.00
Data Structures 380 430.00
C Programming 260 450.00
Learn C++ 350 520.00
DBMS Guide 850 775.00
핵심 정리
qsort() 함수는 총 네 개의 인자를 받습니다. ① 정렬할 배열의 포인터, ② 요소의 개수, ③ 각 요소의 크기(sizeof), ④ 비교 함수입니다. 비교 함수에서 반환값의 부호만 조절하면 오름차순과 내림차순은 물론, 구조체의 특정 멤버를 기준으로 한 정렬도 손쉽게 구현할 수 있습니다. 특히 구조체 값을 값 자체로 직접 전달받는 비교 함수는 qsort()와 호환되지 않으므로, 반드시 const void* 포인터로 받은 뒤 내부에서 적절한 타입으로 형 변환해야 한다는 점을 꼭 기억하세요.