C언어 함수 포인터 (Function Pointer)

코딩C언어
읽는데 9분 소요
처음 쓰여진 날: 2026-04-19
마지막 수정일: 2026-04-19
조회수: 1

요약

C언어 함수 포인터의 선언 문법과 호출 방법을 알아봅니다. int* (*fn)(int*) 같은 복잡한 선언 해석, 구조체 멤버로 함수 포인터 사용, 호출 시 역참조 연산자 순서까지 정보처리기사 실기 26년1회 기출 대비 핵심 개념을 정리합니다.

함수 포인터 핵심 정리

아래 표는 이 페이지에서 다룰 개념을 미리 정리한 것입니다. 지금 바로 이해가 안 돼도 괜찮습니다. 아래 본문에서 하나씩 풀어서 설명합니다.

개념설명예시
함수 포인터 선언함수의 주소를 저장하는 포인터int (*fp)(int);
함수 이름그 자체가 함수의 시작 주소fp = dummy; (&dummy와 같음)
함수 포인터 호출저장된 함수를 실행fp(3) 또는 (*fp)(3)
구조체 멤버 함수 포인터구조체 안에 함수 포인터를 멤버로 두기struct { int (*fn)(int); } s;

함수 포인터란? 기초

프로그램을 실행하면 함수 코드도 메모리 어딘가에 올라갑니다. 그 시작 위치에는 주소가 있고, C언어는 이 주소를 변수에 담을 수 있습니다. 이것이 함수 포인터(Function Pointer) 입니다.

포인터는 "주소를 저장하는 변수"입니다. 변수 포인터가 int 같은 값이 들어 있는 주소를 담듯, 함수 포인터는 함수 코드가 시작되는 주소를 담습니다.

처음 보면 int (*fp)(int) = add; 한 줄에 모르는 문법이 여러 개 겹쳐 있습니다. 아래에서 하나씩 분리해서 이해하고, 마지막에 합쳐서 읽겠습니다.

1단계: 함수 포인터 선언int (*fp)(int);

int를 받아 int를 돌려주는 함수의 주소를 담을 수 있는 포인터 fp를 선언합니다. 선언 문법의 세부 내용은 아래 섹션에서 자세히 다룹니다.

2단계: 함수 이름은 주소다add

add라는 함수 이름은 그 자체로 함수가 올라간 메모리 주소를 의미합니다. &add라고 써도 같은 주소이지만, 관습적으로 &를 생략합니다.

3단계: 포인터에 주소 저장fp = add;

변수 포인터에 변수 주소를 넣듯(int *p = &x;), 함수 포인터에 함수 주소를 넣습니다.

4단계: 저장된 주소로 호출fp(10)

fp에는 add의 주소가 들어 있습니다. fp(10)을 실행하면 C언어가 그 주소로 이동해 add(10)을 실행합니다. 결과는 add(10)10 + 111입니다.

c
코드 하이라이팅 중...

함수 포인터에서 *는 두 가지 전혀 다른 역할로 등장합니다.

위치코드 예*의 역할
선언부int (*fp)(int);"fp는 포인터다"라는 표시 (타입 선언)
호출부(*fp)(10)fp가 가리키는 함수로 이동 (역참조1)

(*fp)(10) 호출 방식은 "포인터가 가리키는 함수를 역참조해서 호출"하는 원형 표기입니다. 현대 C언어는 fp(10) 축약 표기도 허용하므로 두 방식이 동일합니다.


함수 포인터 선언 문법 기초

함수 포인터 선언은 처음 볼 때 복잡해 보이지만, 세 부분으로 나눠서 읽으면 쉽습니다.

c
코드 하이라이팅 중...
위치의미
int (맨 앞)이 함수가 반환하는 자료형
(*fp)이름은 fp, 그 앞의 *는 "포인터"라는 표시
(int) (맨 뒤)이 함수가 받는 매개변수 자료형

int (*fp)(int);"int 하나를 받아서 int를 돌려주는 함수의 주소를 저장하는 포인터 fp" 를 뜻합니다.

괄호가 꼭 필요한 이유

(*fp) 의 괄호를 빼고 int *fp(int); 이라고 쓰면 완전히 다른 의미가 됩니다.

선언해석
int (*fp)(int);int를 받아 int를 돌려주는 함수의 포인터
int *fp(int);int를 받아 int 포인터를 돌려주는 함수의 프로토타입

*를 먼저 fp에 묶어야 "fp는 포인터"가 되기 때문에 괄호 ( ) 가 필요합니다.

반환형이 포인터인 경우

반환형 자리에 int*처럼 포인터 타입을 쓸 수도 있습니다.

c
코드 하이라이팅 중...

이 선언은 "int*를 받아 int*를 돌려주는 함수의 포인터 fp"입니다. 26년1회 기출 문제의 int* (*fn)(int*) 가 바로 이 형태입니다.


함수 포인터에 함수 할당 기초

선언된 함수 포인터에 실제 함수를 연결하려면 함수 이름을 대입합니다.

c
코드 하이라이팅 중...

함수 이름은 변수와 달리 이름 자체가 주소입니다. 변수 포인터와 나란히 놓고 보면 차이가 명확합니다.

c
코드 하이라이팅 중...

fp = add; 는 "fp에 add 함수의 시작 주소를 저장"하는 것이므로, fp = &add; 와 같은 의미입니다.

대입 시 두 함수의 매개변수 개수·위치별 타입·반환 타입이 세 가지 모두 일치해야 합니다. 하나라도 다르면 컴파일 경고(GCC) 또는 오류(MSVC)가 납니다.


함수 포인터로 함수 호출 기초

함수 포인터에 함수를 연결한 뒤에는 일반 함수처럼 호출합니다.

c
코드 하이라이팅 중...

두 가지 호출 방식이 모두 허용됩니다.

표기해석
fp(10)"fp가 가리키는 함수에 10을 넘겨 호출" (권장)
(*fp)(10)"fp를 역참조한 함수에 10을 넘겨 호출" (원형)

C 언어는 두 표기를 똑같이 처리하므로, 시험에서는 어느 쪽이 나와도 같은 의미로 읽으면 됩니다.

시험 출제 경향: 정보처리기사 실기에서는 (*fp)(인자) 역참조 형태가 주로 출제됩니다. 두 방식이 동일하다는 것만 기억하면 어느 표기가 나와도 당황하지 않습니다.


구조체 멤버로 함수 포인터 두기 심화

구조체 안에도 함수 포인터를 멤버로 넣을 수 있습니다. 예를 들어 "학생 구조체에 점수를 계산하는 함수를 함께 담는다"처럼, 데이터(멤버 변수)와 행동(함수 포인터)을 하나의 구조체로 묶는 패턴입니다.

c
코드 하이라이팅 중...

코드 해석 순서

  1. struct fns { int* (*fn)(int*); } mine;
    • } 닫는 중괄호 바로 뒤에 변수명 mine을 붙이면 구조체 타입 정의와 변수 선언을 한 줄에 할 수 있습니다. struct fns mine;을 따로 쓰는 것과 결과가 같습니다. 이 문법은 구조체 페이지의 즉시 변수 선언 섹션에서 자세히 다룹니다.
    • mine.fn은 "int*를 받아 int*를 돌려주는 함수"의 주소를 담을 수 있습니다.
  2. mine.fn = dummy;
    • dummyint*를 받아 int*를 돌려주는 함수이므로 시그니처가 일치합니다.
    • 이제 mine.fn을 호출하면 dummy가 실행됩니다.
  3. *mine.fn(n)
    • 호출 표기를 분해하면 *( mine.fn(n) ) 입니다. 뒤에서 자세히 다룹니다.

*mine.fn(n) 의 연산자 우선순위

함수 호출 () 는 역참조 * 보다 우선순위가 높습니다. 따라서 *mine.fn(n)은 다음 순서로 해석됩니다.

단계수행 내용결과
1mine.fn — 구조체 멤버로 저장된 함수 포인터를 꺼냄dummy 함수의 주소
2mine.fn(n) — 꺼낸 함수에 n을 넘겨 호출 (= dummy(n))n + 1 (배열 두 번째 요소의 주소)
3*mine.fn(n) — 2단계의 반환값(주소)에 역참조n[1] = 32

2단계에서 n + 1이 두 번째 요소 주소인 이유: 배열 이름 n은 첫 번째 요소 n[0]의 주소입니다. int 포인터에 1을 더하면 다음 int 크기(4바이트)만큼 이동하므로 n + 1n[1]의 주소가 됩니다.

n[] = {16, 32} 이고 dummy(n)n + 1을 돌려주므로, 역참조 결과는 두 번째 요소 32입니다.

printf("%x", 32)32를 16진수로 출력합니다. 32를 16진수로 변환하면 32 ÷ 16 = 2 나머지 0이므로 20이 나옵니다. %x는 16진수를 소문자로 출력하는 서식 지정자입니다.

구조체 멤버 함수 포인터 *mine.fn(n) 실행 흐름: mine.fn으로 dummy 함수 주소를 꺼내고, dummy(n)을 호출해 n+1(주소 104)을 반환받은 뒤, 역참조하여 n[1]=32를 얻어 %x로 20을 출력하는 3단계
*mine.fn(n) 3단계 실행 흐름 — 멤버 접근 → 함수 호출 → 역참조

정보처리기사 실기 대비 문제 기초


Footnotes

  1. 역참조: *를 사용해 포인터가 가리키는 주소로 이동해 그 내용에 접근하는 연산입니다. 변수 포인터에서는 *p로 값을 읽고, 함수 포인터에서는 (*fp)(인자)로 함수를 실행합니다.


후수학습(1개)

관련 글

(35개)
제목태그시험
C언어 구조체 배열
C언어
-
C언어 구조체 포인터
C언어
-
C언어 함수 프로토타입
C언어
-