본문
C의 기억부류(Storage Class)와 변수 #1. 범위, 연계, 수명
C는 변수들을 위해 서로다른 5개의 기억모델 즉, 기억부류를 제공한다. 각각의 기억부류를 구분하기 전에 알아야 할 개념으로 변수의 수명(Storage Duration), 변수의 범위(Scope), 변수의 연계(Linkage)이라는 세가지 속성이 있다. 수명이란, 변수가 얼마나 메모리에 유지되는지. 범위란, 소스코드의 어느부분이 해당이름으로 그 변수를 사용할 수 있는지. 연계란, 프로그램을 구성하는 여러개 소스코드 파일들 중 어느 파일에서 그 변수가 사용되는지를 나타낸다.
* 범위(Scope)
프로그램이 어떤 식별자에 접근할 수 있는 영역. C의 변수는 블록범위, 함수 프로토타입 범위, 파일범위, 함수범위 중에서 한 범위를 가진다.
- 블록범위: 중괄호( '{' 와 '}' )로 묶인 일반적인 코드영역(이를 블록이라 한다). 전통적으로 블록 시작위치에 변수를 선언해야 하는데 C99부터 그 규칙이 완화되어 어디서나 변수를 선언할 수 있으며 또한 for () 제어부가 블록에 포함되어, 이 안에서도 변수를 선언할 수 있게 되었다
- 함수 프로토타입 범위: 함수 정의부분에서, 변수들이 정의된 시점부터 프로토타입 선언의 끝까지. 컴파일러는 오직 변수들의 데이터형에만 관심을 가지고 변수이름에는 관심이 없다.
- 파일범위: 어떤 함수에도 속하지 않고 함수 바깥에 놓인 변수. 자신이 정의된 지점으로부터 그 파일의 끝까지 적용된다. 하나이상의 함수에서 사용할 수 있으므로 전역변수(Global Variable)이라 부른다.
- 함수범위: goto 명령문에 의해 사용되는 레이블에만 적용. 즉, 특정 함수 안에 있는 goto 레이블은 함수 어디에 나타나도 그 레이블을 인식할 수 있다.
* 연계(Linkage)
C의 변수는 외부연계(External Linkage), 내부연계(Internal Linkage), 무연계(No Linkage)중 하나를 가진다.
파일범위 변수는 내부연계나 외부연계중 어느 하나를 가진다. 기억부류 지정자 Static를 변수에 붙이면 특정 파일에 대해서만 유효(내부연계)
- 외부연계: 여러 파일로 구성된 프로그램의 어디서나 사용될 수 있다.
- 내부연계: 하나의 파일안의 어디에서나 사용될 수 있다.
- 무연계: 블록범위 변수나 프로토타입 범위 변수는 연계를 가지지 않는다. 즉, 그들이 정의된 블록이나 프로토타입에만 적용된다.
* 수명(Storage Duration)
C의 변수는 정적수명(Static Storage Duration)과 자동수명(Automatic Storage Duration)중 하나를 가진다.
- 정적수명: 프로그램이 실행되는 내내 존재한다. 모든 파일범위 변수는 정적수명을 가진다.
- 자동수명: 정의된 블록에 프로그램이 진입할때 메모리가 할당되고, 블록을 탈출할 때 메모리가 해제된다. 블록범위 변수는 일반적으로 자동 수명을 가진다.
위의 세가지 속성(수명, 범위, 연계)을 조합하여 5가지 기억부류를 나누면 다음과 같다. 참고로 이 구분방법은 Stephen Prata의 'C 기초플러스(C Primer Plus)' 책에서 나온 방법이고, 일반적으로는 c에서 제공하는 기억부류 지정자 (auto, extern, static, register)를 기준으로 기억부류를 4가지로 구분하기도 한다. 또한 Prata는 이 5가지 기억부류를 블록범위(자동변수, 레지스터, 무연계 정적기억부류), 파일범위(외부연계정적, 내부연계정적)의 두가지 카테고리로 크게 나누기도 한다. 즉, 소스파일이 하나만 있다고 범위를 좁힌채 해당 블록에서의 변수의 작동에 대해 알아보는 '블록범위' 라는 카테고리와, 여러 파일들이 있을때 각 파일들에서 변수를 접근가능한지 대해 알아보는 '파일범위'라는 카테고리로 나누어 생각할 수 있게 하였다. (큰 의미는 없다)
추가로 4가지 기억부류 지정자 각각에 대한 수명, 범위, 연계 특성을 요약하면 다음과 같다.
- Auto: 자동수명을 가지는 변수를 나타냄. 블록범위 변수선언에만 사용가능.
- Register: 블록범위 변수에만 사용가능.
- Static: 정적수명을 갖는다. 블록범위와 무연계를 유지. 파일범위 변수를 선언하는데에 사용하면 그변수는 내부연계를 가진다.
- Extern: 이미 정의되어있는 변수를 재선언한다는것을 나타냄. (참조되는 변수는 반드시 외부연계를 가져야한다)
댓글