프로그래밍시스템 프로그래머

C에서 함수 포인터 선언 및 사용의 특징을 설명하십시오. 다양한 함수를 동적으로 호출하기 위해 함수 포인터 배열을 올바르게 저장하는 방법은 무엇입니까?

Hintsage AI 어시스턴트로 면접 통과

답변

C에서 함수 포인터는 함수의 주소를 저장하는 변수로, 어떤 함수를 호출할지를 동적으로 선택할 수 있게 해줍니다. 함수 포인터의 일반적인 선언은 다음과 같습니다:

// int를 받아서 int를 반환하는 함수 포인터 int (*f_ptr)(int);

함수 포인터 배열의 경우:

int func1(int x) { return x + 1; } int func2(int x) { return x * 2; } int (*f_arr[2])(int) = { func1, func2 }; int result = f_arr[1](10); // 20을 반환합니다.
  • 이러한 접근 방식은 명령어 테이블, 핸들러를 만들거나 작업을 작업 번호에 자동으로 연결하는 것을 가능하게 합니다.
  • 모든 함수는 동일한 시그니처를 가져야 합니다.
  • 함수 포인터를 사용할 때는 타입이 정확히 일치해야 합니다.

함정 질문

다른 시그니처를 가진 함수를 호출하기 위해 함수 포인터를 사용할 수 있습니까?

자주 잘못된 답변: "네, 타입 캐스팅을 사용하면 됩니다."

올바른 답변: 기술적으로 이는 포인터의 동적 특성으로 인해 가능하지만, 이러한 행위는 런타임 버그 및 예측할 수 없는 동작을 초래합니다. 호출 규약 및 인수 배치가 다른 함수가 호출되기 때문입니다.

예:

void funcA(int x) { printf("A: %d ", x); } void funcB(float y) { printf("B: %f ", y); } void (*fptr)(int) = (void (*)(int)) funcB; fptr(5); // 오류: 잘못된 데이터가 전달됩니다.

주제에 대한 미세한 차이를 모르고 발생한 실제 오류의 예


이야기

플러그인 시스템 프로젝트에서 서로 다른 시그니처를 가진 함수를 가진 포인터 배열을 생성했습니다 (하나는 int를 반환하고 다른 하나는 void). 일부 아키텍처에서 실행 시 스택이 손상되었습니다.

이야기

구형 명령어 관리 시스템에서 함수 포인터 배열을 사용했습니다. 신입이 추가 매개변수가 있는 함수를 추가하여 배열의 새 요소로 전환한 후 예측할 수 없는 실행이 발생했습니다.

이야기

펌웨어에서 함수 포인터 변경 결과를 확인하지 않았습니다. 핸들러 배열의 초기화 부족으로 인해 NULL 포인터가 호출되어 장치가 사용자에게 알림 없이 정지되었습니다.