qsort 함수에서 사용할 정렬 함수(compare 함수)를 작성할 때, 자료형에 따라 포인터와 포인터의 포인터를 다루는 방법이 다릅니다. 이번 글에서는 int형 배열과 문자열 배열을 정렬하기 위한 compare 함수 작성법을 설명하겠습니다.
먼저, int형 배열을 정렬하는 compare 함수를 살펴보겠습니다.
int compare(const void *a, const void *b) {
return (*(int *)a - *(int *)b);
}
이 함수는 두 개의 const void 인수를 받아서 그들이 가리키는 int 값을 비교합니다. 여기서 가 두 번 사용되는 이유는 다음과 같습니다:
(int )a: void 포인터 a를 int 포인터로 캐스팅합니다. 이는 a가 int형 데이터를 가리키고 있음을 컴파일러에게 알려줍니다.
(int )a: 캐스팅된 int 포인터를 역참조(dereference)하여 실제 int 값을 가져옵니다.
즉, (int )a는 void 포인터 a가 가리키는 메모리 주소에서 int 값을 읽어오는 것입니다. (int *)b도 동일하게 동작합니다.
이번에는 문자열 배열을 정렬하는 compare 함수를 살펴보겠습니다.
int compare(const void *a, const void *b) {
return strcmp(*(const char **)a, *(const char **)b);
}
이 함수는 두 개의 const void 인수를 받아서 그들이 가리키는 문자열을 비교합니다. 여기서 가 세 번 사용되는 이유는 다음과 같습니다:
(const char )a: void 포인터 a를 const char * 포인터의 포인터(const char )로 캐스팅합니다. 이는 a가 const char 타입의 데이터를 가리키고 있는 포인터임을 컴파일러에게 알려줍니다.
(const char )a: 캐스팅된 const char 포인터를 역참조(dereference)하여 실제 const char 값을 가져옵니다. 이 const char 는 문자열을 가리키는 포인터입니다.
strcmp((const char **)a, (const char )b): strcmp 함수에 두 개의 문자열 포인터를 전달하여 문자열을 비교합니다.
즉, *(const char )a는 void 포인터 a가 가리키는 메모리 주소에서 const char 포인터를 읽어오고, 그 포인터가 가리키는 문자열을 비교합니다. (const char **)b도 동일하게 동작합니다.
#include <stdio.h>
#include <stdlib.h>
int compare(const void *a, const void *b) {
return (*(int *)a - *(int *)b);
}
int main() {
int arr[] = {5, 2, 9, 1, 5, 6};
int size = sizeof(arr) / sizeof(arr[0]);
qsort(arr, size, sizeof(int), compare);
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int compare(const void *a, const void *b) {
return strcmp(*(const char **)a, *(const char **)b);
}
int main() {
const char *arr[] = {"banana", "apple", "orange", "kiwi"};
int size = sizeof(arr) / sizeof(arr[0]);
qsort(arr, size, sizeof(const char *), compare);
for (int i = 0; i < size; i++) {
printf("%s ", arr[i]);
}
printf("\n");
return 0;
}