C typedef 완전 가이드: 타입 별칭, 구조체 간소화, 함수 포인터, #define과 차이
typedef는 기존 타입에 새 이름을 부여하는 키워드입니다. 코드 가독성, 이식성, 추상화 수준을 높이는 핵심 도구입니다.
기본 문법
typedef 기존_타입 새_이름;
변수 선언 문법에서 변수 이름 위치에 새 타입 이름을 넣는다고 생각하면 쉽습니다.
기본 타입 별칭
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
typedef int8_t int8_t;
typedef int16_t int16_t;
typedef int32_t int32_t;
typedef int64_t int64_t;
typedef float float32_t;
typedef double float64_t;
// 사용
uint32_t id = 42;
float64_t price = 19.99;
구조체/공용체/열거형 간소화
// 구조체
typedef struct {
int x, y;
} Point;
Point p = {10, 20}; // struct Point p; 불필요
// 공용체
typedef union {
int i;
float f;
} IntFloat;
// 열거형
typedef enum { RED, GREEN, BLUE } Color;
Color c = RED;
포인터 타입 별칭
typedef int *IntPtr;
IntPtr p1, p2; // 둘 다 int*
// 주의: const 위치
typedef char *String;
const String s = "hello"; // char *const s (포인터 상수)
// const char *s 의도였다면:
typedef const char *CString;
함수 포인터 별칭 (가장 큰 효과)
// 복잡한 함수 포인터 타입 단순화
typedef int (*CompareFunc)(const void *, const void *);
typedef void (*Callback)(void *arg);
typedef int (*Handler)(int code, const char *msg);
// 사용
CompareFunc cmp = strcmp;
Callback cb = my_callback;
Handler h = handle_error;
// qsort 예제
void sort_int(int *arr, size_t n, CompareFunc cmp) {
qsort(arr, n, sizeof(int), cmp);
}
배열 타입 별칭
typedef int Matrix[4][4];
Matrix m; // int m[4][4];
Matrix *mp = &m; // int (*)[4][4]
// 함수 매개변수로 배열 타입 전달 (크기 정보 유지)
void init_matrix(Matrix m) { ... } // 실제로는 int (*)[4]로 조정됨
typedef vs #define
| 특성 | typedef | #define |
| 처리 시점 | 컴파일러 (타입 시스템) | 전처리기 (텍스트 치환) |
| 타입 검사 | O | X |
| 스코프 규칙 | 따름 (블록/파일 스코프) | 따르지 않음 (전역 치환) |
| 포인터/const | 올바르게 해석 | 텍스트 치환으로 오류 유발 |
| 디버거 심볼 | 보임 | 안 보임 |
| 값 상수 정의 | 불가 | 가능 (#define MAX 100) |
| 매크로 함수 | 불가 | 가능 |
#define 함정 예시
#define PTR int*
PTR p1, p2; // 전개: int* p1, p2; → p1만 포인터, p2는 int! (버그)
typedef int *Ptr;
Ptr p1, p2; // 둘 다 int* ✓
고급 패턴
불완전 타입으로 캡슐화 (Opaque Pointer)
// public.h
typedef struct Context Context; // 전방 선언 + typedef
Context *context_create();
void context_destroy(Context *);
void context_process(Context *, int);
// private.c
struct Context {
int state;
double buffer[1024];
// 구현 세부사항 은닉
};
플랫폼 독립 타입 정의
// platform.h
#if defined(_WIN64)
typedef __int64 intptr_t;
typedef unsigned __int64 uintptr_t;
#elif defined(__LP64__)
typedef long intptr_t;
typedef unsigned long uintptr_t;
#else
typedef int intptr_t;
typedef unsigned int uintptr_t;
#endif
함수 포인터 테이블 (가상 함수 테이블 패턴)
typedef struct {
void (*init)(void *self);
void (*update)(void *self, float dt);
void (*render)(void *self);
void (*destroy)(void *self);
} VTable;
typedef struct {
VTable *vtable;
// 인스턴스 데이터
} Object;
표준 라이브러리 주요 typedef (<stdint.h>, <stddef.h> 등)
| 타입 | 설명 |
int8_t ~ int64_t | 정확한 폭 부호 있는 정수 |
uint8_t ~ uint64_t | 정확한 폭 부호 없는 정수 |
intptr_t, uintptr_t | 포인터 담을 수 있는 정수 |
size_t | 객체 크기 (부호 없음) |
ptrdiff_t | 포인터 차이 (부호 있음) |
wchar_t | 와이드 문자 |
FILE | 파일 스트림 (불완전 타입) |
va_list | 가변 인자 리스트 |
모범 사례
타입 이름에는 _t 접미사 관례 (uint32_t, size_t, pthread_t)
구조체/공용체/열거형은 typedef로 태그 생략
함수 포인터는 반드시 typedef 사용
플랫폼 의존 타입은 헤더로 추상화
#define은 상수값/매크로 함수용으로만 제한
공개 헤더엔 구현 타입 노출하지 말고 불완전 타입 + typedef 제공
C 언어
-
C# Hello World – 첫 C# 애플리케이션 만들기
-
C# 키워드와 식별자 이해: 규칙, 목록, 모범 사례
-
린 머신으로 월드클래스 제조·유지보수 실현: 설비 우수성 실용 가이드
-
ISA, 제어 시스템 안전 평가 및 신뢰성 서적 제3판 출간
-
신간: OEE 프라이머 - 설비 종합 효율, 신뢰성, 유지보수성 마스터하기
-
서평: '디지털라이즈 오어 다이(Digitise or Die)' – IoT 주도 트랜스포메이션 청사진
-
파괴적 기술 시대, 인간성 지키기
-
2021년 코딩 실력 향상을 위한 최고의 프로그래밍 책 17권
-
C 구조체 마스터: 정의, 멤버 접근, 중첩, 정렬, 패딩, 비트필드
-
C typedef 완전 가이드: 타입 별칭, 구조체 간소화, 함수 포인터, #define과 차이