티스토리 뷰

IT/C, C++

[C] 함수포인터 기초

ROGERNM 2023. 7. 16. 17:47

함수포인터 

C 언어에서 함수 포인터(Function Pointer)는 함수를 가리키는 포인터 변수입니다. 다시 말하면, 함수 포인터는 메모리에서 특정 함수의 주소를 저장할 수 있고, 해당 주소를 사용하여 함수를 호출할 수 있게 해 줍니다. 이를 통해 함수를 다른 함수의 인수로 전달하거나, 함수를 동적으로 선택하여 실행할 수 있게 됩니다.

 

함수 포인터의 선언 방법은 다음과 같습니다:

반환_자료형 (*포인터_변수_이름)(매개변수_자료형1, 매개변수_자료형2, ...);

여기서 반환_자료형은 해당 함수의 반환하는 자료형, 매개변수_자료형1, 매개변수_자료형 2,... 는 해당 함수의 매개변수 자료형들을 나타냅니다.

예를 들어, int를 반환하고 int 매개변수를 한 개 가지는 함수를 가리키는 함수 포인터의 선언은 다음과 같습니다:

 

int (*myFunctionPointer)(int);

함수 포인터를 사용하여 함수를 호출하려면 다음과 같이 할 수 있습니다

 

int someFunction(int x) {
    return x * x;
}

int main() {
    int (*myFunctionPointer)(int); // 함수 포인터 선언
    myFunctionPointer = someFunction; // 함수 포인터에 함수 주소 저장

    int result = myFunctionPointer(5); // 함수 포인터로 함수 호출
    printf("%d\n", result); // 출력: 25
    return 0;
}

함수 포인터는 주로 콜백(callback) 함수를 구현하거나, 함수의 동적 호출을 가능하게 하는 등의 상황에서 유용하게 사용됩니다. 이를 통해 프로그램의 유연성과 확장성을 높일 수 있습니다. 하지만 함수 포인터를 사용할 때에는 주의해야 할 점이 있습니다. 함수 포인터가 가리키는 함수와 사용하는 함수의 반환형과 매개변수가 일치해야 하며, 올바른 함수를 가리키도록 유의해야 합니다.

 

함수포인터를 사용할 때 주의할 점 

1. 함수 포인터가 NULL을 가리킬 수 있음:

함수 포인터를 선언한 후에 초기화하지 않으면, 함수 포인터는 NULL 값을 가집니다. 따라서 함수 포인터를 사용하기 전에 항상 유효한 함수 주소로 초기화해야 합니다.

int (*funcPtr)(int, int) = NULL; // 초기화하지 않은 함수 포인터

// funcPtr로 함수를 호출하기 전에 유효한 함수 주소로 초기화해야 함
if (funcPtr != NULL) {
    int result = funcPtr(3, 5);
    printf("Result: %d\n", result);
}

 

2. 함수 시그니처가 일치해야 함:

함수 포인터가 가리키는 함수의 시그니처(반환형과 매개변수)가 일치해야 합니다. 함수 시그니처가 다른 함수를 함수 포인터에 할당하면 예상치 못한 동작이 발생할 수 있습니다.

int add(int a, int b) {
    return a + b;
}

int subtract(int a, int b) {
    return a - b;
}

int (*funcPtr)(int, int);

funcPtr = add; // 정상: add 함수의 주소를 funcPtr에 할당
int result1 = funcPtr(3, 5); // 함수 포인터로 add 함수 호출, 결과: 8

funcPtr = subtract; // 정상: subtract 함수의 주소를 funcPtr에 할당
int result2 = funcPtr(3, 5); // 함수 포인터로 subtract 함수 호출, 결과: -2

// 하지만 아래와 같이 함수 시그니처가 다른 함수를 할당하면 문제가 발생합니다.
int multiply(int a, int b, int c) {
    return a * b * c;
}

funcPtr = multiply; // 잘못됨: 함수 시그니처가 다르므로 예상치 못한 동작이 발생할 수 있음
int result3 = funcPtr(2, 3); // 잘못된 호출, 결과: 예상치 못한 값

 

3. 함수 호출 시점에서 함수 포인터의 유효성 확인:

함수 포인터가 유효한 함수를 가리키는지 항상 확인해야 합니다. NULL인지 아닌지 확인하여 유효한 함수를 호출하는지 체크해야 합니다.

int (*funcPtr)(int, int) = NULL; // 초기화하지 않은 함수 포인터

// 함수 포인터가 유효한 함수를 가리키는지 확인
if (funcPtr != NULL) {
    int result = funcPtr(3, 5);
    printf("Result: %d\n", result);
} else {
    printf("Error: 함수 포인터가 유효하지 않습니다.\n");
}

 

함수 포인터는 C 언어에서 강력한 기능 중 하나이지만, 사용할 때 주의사항을 잘 따라야 합니다. 함수 포인터를 올바르게 사용하면 프로그램의 유연성을 높일 수 있고, 동적인 동작을 구현하는 데 도움이 됩니다.

 

함수포인터 형변환

함수 포인터의 형변환은 함수 포인터를 다른 함수 포인터로 변환하는 것을 의미합니다. C 언어에서 함수 포인터는 특정 함수의 시그니처(반환형과 매개변수)와 일치해야만 할당이 가능합니다. 그러나 때로는 서로 다른 시그니처를 가진 함수 포인터 간에 형변환이 필요할 수 있습니다. 이때, 올바른 형변환을 해주어야 합니다.

함수 포인터 형변환은 다음과 같은 문법을 사용합니다:

 

(반환_자료형 (*)(매개변수_자료형1, 매개변수_자료형2, ...))

예를들면,

int add(int a, int b) {
    return a + b;
}

double divide(double a, double b) {
    return a / b;
}

int main() {
    int (*funcPtr1)(int, int); // 반환형: int, 매개변수: int, int
    double (*funcPtr2)(double, double); // 반환형: double, 매개변수: double, double

    funcPtr1 = add;
    funcPtr2 = divide;

    int result1 = funcPtr1(3, 5); // 함수 포인터 1로 add 함수 호출, 결과: 8
    double result2 = funcPtr2(6.0, 2.0); // 함수 포인터 2로 divide 함수 호출, 결과: 3.0

    // 다른 함수 포인터로 변환할 때 형변환 필요
    int (*funcPtr3)(int, int) = (int (*)(int, int))divide;
    int result3 = funcPtr3(6, 2); // 함수 포인터 3로 divide 함수 호출, 결과: 3

    return 0;
}
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함