programing

함수 포인터의 용도는 무엇입니까?

lovejava 2023. 10. 31. 20:14

함수 포인터의 용도는 무엇입니까?

중복 가능:
함수 포인터의 요점은 무엇입니까?

나는 실제 시나리오에서 함수 포인터가 어디에 사용되는지 이해하려고 합니다.그리고 누가 나에게 다른 함수에 대한 논쟁으로서 함수 자체를 전달해야 하는 실용적인 예를 들어줄 수 있습니까?

함수 포인터는 콜백 메커니즘을 만들고 싶을 때 유용할 수 있으며 함수의 주소를 다른 함수에 전달해야 합니다.

함수 배열을 저장할 때도 유용할 수 있습니다. 예를 들어 동적으로 호출할 때도 사용할 수 있습니다.

콜백 루틴은 지금까지 제시된 가장 일반적인 시나리오인 것으로 보입니다.하지만, 다른 많은 사람들이 있습니다.

(다차원) 배열의 요소가 다음 상태를 처리/처리하는 루틴을 나타내는 유한 상태 기계.이렇게 하면 FSM의 정의가 한 곳(배열)에 유지됩니다.

기능 활성화 및 기능 비활성화는 기능 포인터를 사용하여 수행할 수 있습니다.유사하지만 다른 작업을 수행하는 기능을 사용하거나 사용하지 않도록 설정할 수 있습니다.if-else construct 테스트 변수로 코드를 채우고 어수선하게 하는 대신 함수 포인터를 사용하도록 코드화한 다음 함수 포인터를 변경/할당하여 기능을 활성화/비활성화할 수 있습니다.새로운 변형을 추가하는 경우 if-else 또는 switch 케이스를 모두 추적할 필요가 없으며, 새로운 기능을 사용하도록 기능 포인터를 업데이트하거나 이전 기능을 사용하지 않도록 설정하면 됩니다.

이전 예에서 이에 대해 언급한 코드 클러터 감소.예를 들어...

switch (a) {
case 0:
    func0();
    break;
case 1:
    func1();
    break;
case 2:
    func2();
    break;
case 3:
    func3();
    break;
default:
    funcX();
    break;
}

...로 단순화할 수 있습니다.

/* This declaration may be off a little, but I am after the essence of the idea */
void (*funcArray)(void)[] = {func0, func1, func2, func3, funcX};
... appropriate bounds checking on 'a' ...
funcArray[a]();

더 많습니다.도움이 되길 바랍니다.

일반적으로 사용되는 것 중 하나는 콜백 기능을 구현하는 것입니다.

를 사용하여 무언가를 분류해 봅니다.qsort도서관 기능한 비교기 함수의 포인터입니다.마지막 파라미터는 사용자가 작성한 비교기 함수의 포인터입니다.

아주 유용한 앱으로 가장 먼저 떠오르는 것은 버튼입니다.다음 코드를 사용합니다.

int buttonID = CreateButton ("Click Me!", 100, 100, 200, 100, onClick);

이렇게 하면 너비 200, 높이 100의 (100,100) 버튼이 만들어집니다.클릭할 때마다 onClick이 호출됩니다.

저는 개인 윈도우 API 포장지에 유사한 것을 사용합니다.버튼 등을 훨씬 쉽게 만들 수 있습니다.

함수 포인터의 용도는 크게 두 가지입니다.

  • 콜백 - 이벤트 핸들러, 파서 전문화, 비교기 함수 전달에 사용...
  • 플러그인과 확장자 - 플러그인이나 라이브러리 확장자가 제공하는 함수에 대한 포인터는 표준 함수에 의해 수집됩니다.GetProcAddress,dlsym또는 이와 유사합니다. 함수 식별자를 이름으로 사용하고 함수 포인터를 반환합니다.OpenGL과 같은 API에 절대적으로 중요합니다.

대부분의 경우, 그것은 본질적으로 의존성 반전을 하는 C 방식입니다.위키 기사는 다음과 같이 기술합니다.

A. 높은 수준의 모듈은 낮은 수준의 모듈에 의존해서는 안 됩니다.둘 다 추상화에 의존해야 합니다.나. 추상화는 세부사항에 의존해서는 안 됩니다.세부 사항은 추상화에 따라 달라져야 합니다.

의 전형적인 예는qsort상위 정렬 함수는 정렬할 데이터의 유형, 크기 또는 비교 방법에 따라 달라지지 않습니다.그래서 당신이qsort()일련의 int들, 세부사항들은sizeof(int)그리고 당신의 비교 구현.추상화는 임의 크기의 요소 배열이며 해당 유형의 요소를 비교하는 함수입니다.

참고 항목:제어의 반전.

아무도 언급하지 않았다니 놀랍습니다.pthread_create()예를 들면

의존성 반전으로 일반화할 수 없는 유일한 일반적인 용도는 전환할 수 없는 데이터 유형에 스위치와 같은 흐름 제어를 구현하는 것입니다.예를 들어 문자열을 전환하고 싶은 경우 정렬된 문자열 키를 함수 포인터에 매핑한 배열을 만들고 이진 검색을 수행합니다.스위치와 같은 O(1)가 아니라 일치하는 것을 찾을 때까지 맹목적으로 큰 if-else에서 strcmp()'s를 하는 것보다 낫습니다.하지만 문자열을 토큰화하고 실제 스위치를 사용하는 것보다 나을 수 없습니다.

자, 주식 1위의 답은 다음과 같습니다.qsort. 비교기 루틴은qsortwill use가 함수 포인터로 전달됩니다.다른 많은 "일반 알고리즘" 함수들은 비슷한 방식으로 비교를 수행합니다. 예를 들어 해시 테이블 구현이 해시 함수를 수용할 수도 있습니다.

C 언어 GUI 툴킷과 애플리케이션 프레임워크(예: Gnome/Gtk+/Glib)는 타이머나 사용자 인터페이스 이벤트에 대해 함수 포인터를 "콜백"으로 받아들이는 경우가 많습니다. (예: "이 버튼을 클릭할 때마다 이 함수를 호출" 또는 "…이 타이머가 만료될 때마다")

사실, C의 대부분의 "OOP-like" 코드나 "Event-driven" 코드는 비슷한 이유로 함수 포인터를 받아들입니다.

함수에 콜백을 전달하는 데 사용할 수 있습니다.예를 들어, 다음을 사용하여 배열을 정렬할 수 있습니다.qsort()는 인수 중 할 수 이 함수는 인수 중 하나로 비교 함수를 사용하며, 이는 사용자 자신의 정렬 순서를 사용할 수 있음을 의미합니다.

// All odd numbers are before even numbers
int cmpoddeven(const void *xp, const void *yp) {
  int x = *((int*) xp);
  int y = *((int*) yp);
  if(x == y)
    return 0;
  if(x % 2 == y % 2) {
    return (x < y ? -1 : 1);
  if(x % 2 == 1)
    return -1;
  return 1;
}

int main() {
   int array[] = {1, 2, 3, 4, 5};
   // calling qsort with cmpoddeven as the comparison function
   qsort(array, 5, sizeof(int), &cmpoddeven);
   // array == {1, 3, 5, 2, 4};
}

언급URL : https://stackoverflow.com/questions/8975208/what-is-the-use-of-function-pointers