이런 분들이 찾고 있어요
이 레슨과 관련된 학습 키워드
코드를 읽고 설명하면, 합격합니다
이 레슨과 관련된 학습 키워드
C 프로그래밍 — 하드웨어에 가장 가까운 언어 → 시스템 프로그래밍
int (*op)(int, int);qsort(), bsearch() 등 표준 라이브러리가 비교 함수를 인자로 받음 (Kernighan & Ritchie, 1988)apply 함수)1# === C 함수 포인터 개념을 Python으로 체험 ===💡2# (C의 함수 포인터 ↔ Python의 일급 함수 대응)3import random💡4random.seed(42)💡5 6# --- 1) 기본: 함수를 변수에 저장 ---7def add(a, b):💡8 return a + b💡9 10def mul(a, b):💡11 return a * b💡12 13op = add💡14print(f"op(3,4) = {op(3,4)}")💡15op = mul💡16print(f"op(3,4) = {op(3,4)}")💡17 18# --- 2) 콜백 패턴: 함수를 인자로 전달 ---19def apply(func, x, y):💡20 return func(x, y)💡21 22print(f"apply(add,5,6) = {apply(add,5,6)}")💡23print(f"apply(mul,5,6) = {apply(mul,5,6)}")💡24 25# --- 3) 디스패치 테이블: 함수 포인터 배열 ---26def sub(a, b):💡27 return a - b💡28 29dispatch = [add, sub, mul]💡30labels = ["+", "-", "*"]💡31a, b = 10, 3💡32for i, fn in enumerate(dispatch):💡33 print(f" {a} {labels[i]} {b} = {fn(a,b)}")💡34 35# --- 4) typedef 대응: 타입 별칭으로 가독성 향상 ---36from typing import Callable💡37BinOp = Callable[[int,int], int]💡38def execute(op: BinOp, x: int, y: int) -> int:💡39 return op(x, y)💡40print(f"execute(sub,20,7) = {execute(sub,20,7)}")💡오늘은 함수 포인터가 무엇인지 살펴보겠습니다.
C에서 함수도 메모리에 기계어로 적재됩니다.
그 시작 주소를 저장하는 변수가 함수 포인터예요.
일반 포인터가 데이터를, 함수 포인터는 코드를 가리킵니다.
그림 상단을 보시면 선언 문법이 두 가지로 나뉩니다.
왼쪽이 올바른 함수 포인터 선언입니다.
괄호 안에 *op를 넣어야 op가 포인터라는 의미가 됩니다.
오른쪽은 포인터를 반환하는 함수 선언으로 완전히 다릅니다.
괄호 하나 차이로 의미가 바뀌니 꼭 주의하세요.
이어서 함수명의 자동 디케이를 보겠습니다.
그림 가운데 메모리 영역을 보시면 각 함수의 주소가 나옵니다.
add라는 이름 자체가 함수의 시작 주소로 자동 변환돼요.
함수명과 주소 연산자 두 방식 모두 같은 주소를 줍니다.
직접 호출은 컴파일 시점에 어떤 함수를 부를지 결정됩니다.
간접 호출은 런타임에 op가 가리키는 함수를 호출합니다.
op가 NULL이면 세그폴트가 나니 꼭 초기화하세요.
이제 코드를 같이 볼게요.
코드 첫 번째 섹션을 보시면 op에 add를 저장하고 호출합니다.
op를 mul로 바꾸면 런타임에 다른 함수가 실행됩니다.
두 번째 섹션은 콜백 패턴으로 apply가 함수를 인자로 받습니다.
큐소트의 비교 함수 인자와 완전히 같은 원리예요.
세 번째 섹션은 디스패치 테이블입니다.
그림 하단을 보시면 배열에 add, sub, mul이 담겨 있어요.
인덱스로 함수를 선택하면 if나 switch 없이 분기가 됩니다.
i가 0이면 13, 1이면 7, 2이면 30이 반환됩니다.
마지막으로 typedef를 쓰면 선언이 훨씬 깔끔해집니다.
BinOp처럼 별칭을 만들면 복잡한 선언이 한 줄로 줄어들어요.
하단 요약을 보시면 핵심 네 가지가 정리되어 있습니다.
NULL 초기화, 시그니처 일치, void 포인터 비호환을 기억하세요.