저장 클래스(Storage Class)의 개념
C 언어에서 저장 클래스(storage class)는 변수의 범위(scope), 수명(lifetime), 그리고 바인딩(binding)을 결정합니다. 변수를 완전하게 정의하려면 데이터 '타입'뿐만 아니라 저장 클래스까지 함께 명시해야 합니다.
변수 이름은 컴퓨터 메모리 내의 특정 물리적 위치를 가리키며, 그 위치에는 변수 값을 저장하기 위한 비트들이 할당되어 있습니다.
저장 클래스가 알려주는 핵심 정보는 다음과 같습니다.
- 변수가 어디에 저장되는가? (메모리 또는 CPU 레지스터)
- 아무것도 초기화하지 않았을 때 변수의 기본값은 무엇인가?
- 변수의 범위(scope)는 어디까지인가? (어디에서 접근 가능한가?)
- 변수의 수명(life)은 얼마나 되는가?
바인딩(Binding)이란?
바인딩은 식별자(identifier)가 사용(applied occurrence)된 지점에 대해 대응하는 선언 또는 정의(binding occurrence)를 찾아 연결하는 과정입니다. 바인딩을 올바르게 이해하려면 다음 사항을 먼저 파악해야 합니다.
- 변수의 범위(scope)를 정확히 알고 있어야 합니다.
그렇다면 블록 구조(block structure)란 무엇이며, 식별자는 어떤 블록에서 변수로 인식될까요?
- 같은 식별자 이름을 다시 사용하면 어떻게 될까?
C 언어는 동일한 범위(scope) 안에서 같은 식별자 이름의 재사용을 금지합니다. 반면, 서로 다른 범위라면 같은 이름을 자유롭게 사용할 수 있습니다.
예제 1: 잘못된 선언 (컴파일 오류)
double f,y;
int f( ) // 오류: f가 이미 double 변수로 선언됨
{
---
----
----
}
double y; // 오류: 전역 범위에서 y가 중복 선언됨
위 코드에서 f는 이미 전역 범위에서 double형 변수로 선언되었으므로, 같은 이름으로 함수를 정의할 수 없습니다. 마찬가지로 y 역시 전역 범위에서 중복 선언되어 오류가 발생합니다.
예제 2: 유효한 선언 (다른 범위에서의 이름 재사용)
double y;
int f( ){
double f; // 유효: 함수 내부의 지역 변수
int y; // 유효: 함수 내부의 지역 변수
}
함수 f() 내부에서 f와 y를 지역 변수로 선언하는 것은 문법적으로 유효합니다. 전역 변수와 지역 변수는 서로 다른 범위에 속하기 때문에 같은 이름이라도 충돌하지 않습니다.
예제 3: 변수 바인딩을 보여주는 C 프로그램
다음은 중첩된 블록에서 변수의 바인딩이 어떻게 달라지는지 보여주는 C 프로그램입니다.
#include<stdio.h>
int i=33;
main() {
extern int i; {
int i=22; {
const volatile unsigned i=11;
printf("i=%d\n",i);
}
printf("i=%d",i);
}
}
실행 결과
위 프로그램을 실행하면 다음과 같은 출력 결과를 얻습니다.
i=11 i=22
가장 안쪽 블록에서는 i가 11로 출력되고, 해당 블록을 벗어나면 바인딩이 외부 블록의 i=22 선언으로 되돌아갑니다. 이처럼 각 블록마다 새로운 i가 선언되면 가장 가까운(내부) 선언이 우선 적용되며, 블록을 빠져나가면 이전 범위의 선언에 다시 바인딩됩니다.