C/C++ static 키워드 완벽 정리: 내부 static vs 외부 static

By | 2026년 8월 7일
Table of Contents

C/C++ static 키워드 완벽 정리: 내부 static vs 외부 static

C 언어 및 C++ 프로그래밍을 배우다 보면 가장 자주 접하면서도 초보자들이 흔히 헷갈려 하는 키워드 중 하나가 바로 static입니다.

흔히 Brian Kernighan과 Dennis Ritchie가 지은 C 언어의 기본서 K&R C (The C Programming Language)4장(Functions and Program Structure)에서도 static 키워드는 중요한 개념으로 다루어집니다.

C/C++에서 static은 선언되는 위치(함수 내부 vs 파일 스코프)에 따라 완전히 다른 두 가지 역할을 수행합니다. 이번 포스팅에서는 static 키워드의 개념과 동작 방식, 그리고 실무에서의 사용 예제를 정리해 보겠습니다.


1. static 키워드의 핵심 개념

static 키워드는 기본적으로 다음 두 가지 속성을 제어합니다.

  1. 저장 수명 (Storage Duration): 변수가 메모리에 유지되는 기간 (프로그램 시작부터 종료까지)
  2. 연결성 / 가시성 (Linkage / Visibility): 해당 식별자(변수 또는 함수)를 어느 범주까지 참조할 수 있는지

2. 내부 static 변수 (Internal Static Variables)

함수 내부에 선언된 static 변수입니다.

특징

  • 수명(Lifetime): 함수가 호출될 때 생성되는 일반 지역 변수(auto)와 달리, 프로그램이 실행될 때 메모리(Data/BSS 영역)에 할당되어 프로그램이 종료될 때까지 남아있습니다.
  • 초기화: 프로그램 시작 시 단 한 번만 초기화됩니다. (초기값을 지정하지 않으면 기본적으로 0으로 자동 초기화)
  • 스코프(Scope): 변수가 선언된 함수 내부에서만 접근 가능합니다.

코드 예제

#include <stdio.h>

void count_calls() {
    static int count = 0; // 프로그램 시작 시 1회만 초기화됨
    int local_var = 0;    // 함수 호출 시마다 생성 및 초기화됨

    count++;
    local_var++;

    printf("static count: %d, local_var: %d\n", count, local_var);
}

int main() {
    count_calls(); // static count: 1, local_var: 1
    count_calls(); // static count: 2, local_var: 1
    count_calls(); // static count: 3, local_var: 1
    return 0;
}

언제 사용할까?

  • 함수가 이전 호출 상태를 기억해야 할 때 (예: 호출 횟수 카운팅, 캐싱, 상태 머신 관리)
  • 전역 변수를 쓰기엔 캡슐화가 깨지고, 일반 지역 변수를 쓰기엔 값이 유지되어야 할 때

3. 외부 static 변수 및 함수 (External Static Variables & Functions)

함수 외부(파일 스코프)에 선언된 static 변수 또는 함수입니다.

특징

  • 내부 연결(Internal Linkage)을 가집니다.
  • 선언된 해당 소스 파일(.c) 내에서만 참조할 수 있으며, 다른 파일에서 extern으로 접근하는 것이 불가능합니다.
  • 파일 간의 이름 충돌을 방지하고 정보 은닉(Information Hiding) 및 모듈화를 구현하는 데 쓰입니다.

코드 예제

math_utils.c

#include <stdio.h>

// 이 파일 내부에서만 접근 가능한 static 전역 변수
static int operation_count = 0;

// 이 파일 내부에서만 호출 가능한 static 헬퍼 함수
static void log_operation(const char* op_name) {
    operation_count++;
    printf("[%s] 수행됨 (총 실행 횟수: %d)\n", op_name, operation_count);
}

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

main.c

#include <stdio.h>

int add(int a, int b);

// 아래와 같이 가져오려고 시도하면 링커 에러(Link Error) 발생!
// extern int operation_count; 
// void log_operation(const char* op_name);

int main() {
    printf("Result: %d\n", add(3, 5));
    printf("Result: %d\n", add(10, 20));
    return 0;
}

언제 사용할까?

  • 특정 모듈/파일 내부에서만 사용하는 헬퍼 함수나 상태 변수를 숨기고 싶을 때
  • 라이브러리 작성 시 외부로 노출하는 API와 내부 구현 로직을 분리할 때

4. 요약 정리

구분 위치 수명 (Duration) 스코프/가시성 (Scope/Visibility) 주요 목적
내부 static 함수 내부 프로그램 전체 (Data 영역) 해당 함수 내부 함수 호출 간 상태 유지
외부 static 함수 외부 (파일 단위) 프로그램 전체 (Data 영역) 해당 파일 내부 (Internal Linkage) 모듈화, 정보 은닉, 이름 충돌 방지

마치며

C/C++의 static 키워드는 "메모리 상에는 계속 존재하게 하되, 접근 범위는 제한한다"는 공통된 원리로 작동합니다.

  1. 함수 내부: 전역 메모리에 두되, 접근은 해당 함수로 제한
  2. 파일 외부: 전역 메모리에 두되, 접근은 해당 파일로 제한

이 두 가지 쓰임새를 명확히 이해하고 활용한다면, 보다 안전하고 모듈화된 깔끔한 C/C++ 코드를 작성할 수 있습니다.

답글 남기기