C 저장 클래스 이해: 범위, 생명주기, 성능
C 저장 클래스 이해
자동, 외부, 정적, 레지스터 저장 클래스가 C에서 변수의 범위, 생명주기, 성능을 어떻게 정의하는지 탐구합니다.
자동(로컬) 변수
블록 내 선언된 변수는 자동 변수, 즉 로컬 변수입니다. 해당 블록 내에서만 존재하며 블록 종료 시 소멸합니다.
#include <stdio.h>
int main(void) {
for (int i = 0; i < 5; ++i) {
printf("C programming\n");
}
// 오류: 이 범위에서 i 선언되지 않음
printf("%d", i);
return 0;
}
이 프로그램 실행 시 i가 for 루프 블록 내에서만 선언되었으므로 undeclared identifier i 오류 발생.
int main() {
int n1; // main() 지역
}
void func() {
int n2; // func() 지역
}
여기서 n1은 func() 내부에서 접근 불가, n2는 main()에서 접근 불가.
전역(외부) 변수
모든 함수 밖에 선언된 변수는 전역 또는 외부 변수입니다. 같은 번역 단위 내 어떤 함수에서도 접근 가능. 전역 변수가 한 파일에 정의되고 다른 파일에서 사용될 때 extern 키워드로 정의가 다른 곳에 있음을 알립니다.
예제: 전역 변수
#include <stdio.h>
void display();
int n = 5; // 전역 변수
int main() {
++n;
display();
return 0;
}
void display() {
++n;
printf("n = %d\n", n);
}
출력
n = 7
n이 file1.c에 정의되고 file2.c에서 사용되면 file2.c 상단에 extern int n;을 추가해 컴파일 오류 방지.
레지스터 변수
register 키워드는 컴파일러에게 변수를 CPU 레지스터에 저장해 접근 속도를 높이도록 힌트 줍니다. 현대 컴파일러는 적극적 최적화를 수행해 힌트가 불필요한 경우가 많습니다. 임베디드 시스템에서 프로파일링 결과 중요한 병목 지점으로 나타날 때만 register 사용.
정적 변수
static으로 선언된 정적 변수는 프로그램 실행 전체 동안 값을 유지합니다. 프로그램 시작 시 한 번만 초기화되며 프로그램 종료까지 존재합니다.
예제: 정적 변수
#include <stdio.h>
void display();
int main() {
display();
display();
}
void display() {
static int c = 1;
c += 5;
printf("%d ", c);
}
출력
6 11
첫 호출 시 c가 1로 초기화된 후 6으로 증가. 두 번째 호출 시 c는 이전 값 6을 유지해 11로 증가 후 출력.
파일 범위에서 static 선언은 변수에 내부 링키지를 부여해 다른 번역 단위에서 보이지 않게 함 — 캡슐화에 유용.
ISO C 표준에 따르면 static 동작은 모든 함수 호출에 걸쳐 단일 인스턴스를 보장하며, 전역 오염 없이 상태full 연산에 중요합니다.