콜백함수의 인자로써 void 포인터
Intro
지난 게시글에서, 이중포인터와 void 포인터에 대해 간략하게 다뤘다.
https://microelectronics.tistory.com/54
[C/C++] 이중포인터와 void 포인터
이중포인터와 void 포인터 문자열배열은 이중포인터이다 아래와 같이 문자열 배열이 있고, 해당 문자열배열의 주소를 void 포인터에 초기화시켰다고 가정해보자. char* arr[] = {"banana", "apple"}; void* vr
microelectronics.tistory.com
또한 콜백함수에 대해 왜/언제 쓰는지를 알아보았다.
https://microelectronics.tistory.com/46
[C/C++] 콜백함수 (Callback Function)
콜백 함수란? 콜백 함수는 다른 코드의 인자로 전달되어, 그 코드에 의해 어느 시점에 호출되는 함수인데 특히 비동기적 작업, 이벤트 리스닝, 또는 특정 조건 하에서 실행되어야 할 코드 조각을
microelectronics.tistory.com
이를 바탕으로 단일 sort 함수로 다양한 데이터타입을 처리하는 예제를 다뤄보고자 한다.
타입에 맞는 sort 함수
내가 라이브러리를 만드는 개발자로서, sort 와 관련된 라이브러리를 만든다고 가정해보자.
이 경우에는, 여러 데이터 타입에 대응하는 각각의 sort 함수를 생성하는 대신, 사용자가 제공하는 비교 함수를 사용하여 유연하게 작동하는 단일 sort 함수를 설계하는 것이 효율적일 것이다.
이 접근 방식에서 sort 함수는 비교 로직을 처리할 수 있는 '함수 포인터'를 인자로 받는다.
이 함수 포인터는 사용자가 정의한 비교 함수를 가리키며, 이 함수는 sort 함수 내에서 데이터 항목들을 비교하는 데 사용된다.
이렇게 하면, 라이브러리 사용자는 자신의 데이터 타입에 맞는 비교 로직을 작성하여 이를 sort 함수에 전달할 수 있다.
라이브러리 제작자는 이 비교 함수의 프로토타입(즉, 함수의 반환 타입과 매개변수 타입)만 정의해두면 되고,
사용자는 자신의 데이터 타입에 맞는 비교 함수를 정의하고, 이 함수를 sort 함수에 콜백으로 전달하면 된다.
결과적으로, 단 하나의 범용 sort 함수를 제공함으로써 다양한 데이터 타입과 상황에 적합하게 쓰일 수 있는 매우 유연한 정렬 라이브러리를 만들 수 있다.
sort 함수 예시
아래는 주어진 배열에 대해 선택정렬을 실행하는 함수의 예시이다.
void sort(void* arr, int len, int typesize, bool (*cmp)(void* a, void *b)){
void* tmp = (void*)malloc(typesize);
for (int i = 0; i < len - 1; i++){
for ( int j = i; j < len; j++){
if ( cmp ( (char*)arr + i*typesize, (char*)arr + j*typesize)){
memcpy(tmp, (char*)arr + i*typesize, typesize);
memcpy((char*)arr + i*typesize, (char*)arr+j*typesize, typesize);
memcpy((char*)arr + j*typesize, tmp, typesize);
}
}
}
free(tmp);
}
비교를 하는 콜백함수로 cmp 를 마련했고, cmp 는 아래와 같이 정의 가능하다.
주목해야 할 부분은, 어떤 데이터 타입이 올지 모르기때문에 제네릭 포인터인 void 포인터를 비교함수의 인자로 주어줘야 한다는 것이다.
각 비교함수에서는 void 타입 포인터를 실제 데이터타입에 맞게 캐스팅을 해주어야 한다.
지난 게시글에서 문자열배열은 이중포인터라고 다뤘다. 그에 맞게 char** 타입으로 캐스팅을 해줘야 한다는 것을 꼭 이해하고 넘어가야 한다.
bool compare_string(void* a, void*b){
char* str1 = *(char**)a;
char* str2 = *(char**)b;
return strcmp(str1,str2) > 0;
}
bool compare_int(void* a, void* b){
if (*(int*)a > *(int*)b) return 1;
else return 0;
}
C++ - Template
C++ 에서는 다양한 데이터타입에 대한 코드 중복을 줄이기 위해, template 이란 키워드를 제공한다.
template<typename T>
void sort(T* arr, size_t len) {
T tmp;
for (size_t i = 0; i < len; i++) {
for (size_t j = i + 1; j < len; j++) {
if (arr[i] > arr[j]){
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
}
}
코드도 훨씬 간결하고, 가독성 있게 작성할 수 있다.
이게 가능한 이유는 컴파일러가 컴파일타임에 여러 데이터 타입에 해당하는 sort 함수를 자동으로 만들어 주기 때문이다.
출력하는 함수도 마찬가지이다. 템플릿을 사용하면 C와는 다르게 단일 함수로 어떠한 배열이 오더라도 모두 처리할 수 있다.
'SW > C,C++' 카테고리의 다른 글
[C++] std::cin 타입 불일치 (0) | 2024.05.02 |
---|---|
[C/C++] 커널 드라이버에서의 함수포인터 (0) | 2024.04.22 |
[C/C++] 이중포인터와 void 포인터 (0) | 2024.04.20 |
[C/C++] 동적 2차원 배열과 가변길이배열(VLA) (0) | 2024.04.11 |
[C/C++] C++ 에서의 콜백함수 (0) | 2024.04.07 |
댓글