기억 클래스
정의
Storage Class, 기억클래스 또는 저장클래스라고 부른다.
변수의 존속기간(Lifetime), 유효범위(scope), 저장위치(storage location)를 결정하는 개념
기억클래스의 종류에 따라 초기화, 존속기간, 유효범위에 차이가 있다.
구분
영문
설명
존속기간
lifetime
변수의 존재 시간
유효범위
scope
변수의 사용 가능한 영역
저장위치
storage location
변수의 물리적(메모리) 저장 위치
종류
기억 클래스
영문
설명
저장 위치
자동변수
auto
함수 호출 시 생성하고, 함수 종료 시 소멸된다. 지역변수 등.
스택(stack)
정적변수
static
함수 호출 시 생성되고, 프로그램 종료 시 소멸된다.
데이터(data)
외부변수
extern
함수 또는 파일 외부에 정의된 변수를 찾아 연결하는 변수
데이터(data)
레지스터변수
register
CPU의 레지스터에 자료를 저장하도록 하는 변수
CPU레지스터(register)
문법
변수 선언시 자료형의 앞에 기억 클래스를 지정 한다.
1
2
3
기억클래스 자료형 변수명 ; // 선언만
기억클래스 자료형 변수명 = 초기값 ; // 선언+초기화
static int a = 10 ; // 예시
자동변수 auto
개념
지역변수에 적용될 수 있는 기억 클래스
함수 내 선언된 경우 : 함수 호출 시 생성되고, 함수 종료 시 소멸된다.
블록 내 선언돤 경우 : 블록 진입 시 생성되고, 블록 종료 시 소멸된다.
저장 위치 : 스택(stack)
선언 방법
예약어 auto를 지정하여 선언한다.
변수 선언시 기본으로 자동변수로 선언되므로, 생략할 수 있다.
1
2
auto int a = 10 ;
int a = 10 ;
존속기간
생성 : 변수가 소속된 함수나 블록에 진입할 때 생성된다.
소멸 : 소속 함수나 블록에서 빠져나갈 때 소멸한다.
유효범위
초기값
명시적으로 초기화하지 않는 경우, 쓰레기값을 가지게 된다.
따라서 자동변수는 의도와 맞게 적절하게 초기화를 할 필요가 있다.
예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
void main () { // main func
int i = 1 ;
auto int j = 2 ;
{ // block 1
int i = 3 ;
{ // block 2
int i = 4 ;
printf ( "block2 : i = %d \n " , i );
printf ( "block2 : j = %d \n " , j );
}
printf ( "block1 : i = %d \n " , i );
printf ( "block1 : j = %d \n " , j );
}
printf ( "main func : i = %d \n " , i );
printf ( "main func : j = %d \n " , j );
}
1
2
3
4
5
6
block2 : i = 4
block2 : j = 2
block1 : i = 3
block1 : j = 2
main func : i = 1
main func : j = 2
정적변수 static
개념
한 번 생성되면 프로그램 전체 실행 동안 메모리에 계속 유지되느느 변수
지역적으로 선언되더라도 존속기간은 프로그램 실행동안으로 길고, 유효범위는 지역으로 제한되는 특성
자신이 선언된 함수나 블록이 끝나도 사라지지 않고 보존된다.
따라서 함수 호출 간 상태를 유지해야 하는 상황 에서 두루 사용된다.
data 영역 에 저장된다.
선언 방법
존속기간
생성 : 프로그램을 시작할 때 생성 된다.
소멸 : 프로그램을 종료할 때 소멸 된다.
유효범위
함수나 블록 내부 에 선언된 경우 : 소속 함수나 블록 내에서만 사용 할 수 있다.
함수 외부 에 선언된 경우 : 소속 파일에서만 사용할 수 있다.
초기값
명시적으로 초기화하지 않으면, 0으로 초기화된다.
예시
static 변수의 유효범위는 해당 함수나 블록 내부로 제한되나, 존속기간은 프로그램 전체 실행 동안 유지된다는 특성에 주목해서 예시를 볼 것
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
void test ();
int main () {
int i ;
for ( i = 0 ; i < 3 ; i ++ ) {
test ();
}
// printf("s = %d\n", s); ---- 컴파일 에러 발생 (s의 유효범위 밖)
}
void test () {
auto int a = 0 ;
static int s = 0 ;
printf ( "auto = %d, static = %d \n " , a , s );
++ a ;
++ s ;
}
1
2
3
4
auto = 0, static = 0
auto = 0, static = 1
auto = 0, static = 2 #---- s 는 함수 호출이 끝나도 유지된다.
# 따라서 값이 누적되어 더해진다.
외부변수 extern
개념
함수 외부에 선언된 변수를 함수 내부에서 사용할 수 있도록 선언하는 기억 클래스
extern 은 “이 변수는 여기에서 정의 되는 것이 아니라, 다른 곳(파일 등)에서 정의 되어 있으니, 링크 단계에서 그 변수를 찾아서 연결하라” 라는 선언
선언 방법
존속기간
생성 : 프로그램을 시작할 때 생성된다.
소멸 : 프로그램을 종료할 때 소멸된다.
유효범위
프로그램의 전체 범위
다른 파일에서 외부변수로 선언된 변수를 사용할 수 있다.
초기값
명시적으로 초기화하지 않는 경우, 0으로 초기화된다.
예시 1
1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
int i = 10 ;
int j = 20 ;
int main () {
extern int i ;
extern int k ; //---- 외부 변수 선언 위치
int j = 100 ;
printf ( "i = %d, j = %d, k = %d \n " , i , j , k );
}
int k = 50 ; //---- 외부 변수에 대한 정의 위치
1
2
i = 10, j = 100, k = 50
# k 를 선언하지 않았음에도 불구하고 사용할 수 있다.
예시 2
1
2
3
4
5
6
7
8
9
10
11
12
13
// a.c
#include <stdio.h>
#include <stdlib.h>
void extern_ex ();
int a = 100 ;
int main () {
printf ( "file a.c 에서 선언된 변수 a 의 값은 %d" , a );
extern_ex ();
return EXIT_SUCCESS ;
}
1
2
3
4
// b.c
#include <stdio.h>
extern int a ;
void extern_ex () { printf ( "file b.c 에서 변수 a 의 값은 %d" , a ); }
1
2
3
4
5
6
gcc a.c b.c -o test # a.c 와 b.c 를 함께 컴파일하여 test 라는 파일 생성
./test # test 실행
# 출력
file a.c 에서 선언된 변수 a 의 값은 100
file b.c 에서 변수 a 의 값은 100
레지스터 변수 register
개념
CPU의 레지스터에 자료를 저장할 것을 의미한다.
매우 자주 사용되는 변수를 지정해, 실행 속도를 높이려는 목적
예시 : 반복문의 카운터 변수
현대 컴파일러는 register 키워드를 거의 무시한다.
실제 레지스터 배치는 전적으로 optimizer 가 결정한다.
반복문 카운터는 register 키워드를 사용하지 않아도 자동으로 레지스터에 들어간다.
선언 방법
존속기간
자동변수와 동일하다.
생성 : 함수나 블록 내부에서 선언될 때 생성
소멸 : 함수나 블록 내부에서 선언될 때 소멸
유효범위
자동변수와 동일하다.
함수나 블록 내부에서 선언된 경우 : 소속 함수나 블록 내에서만 사용할 수 있다.
초기값
명시적으로 초기화하지 않는 경우, 쓰레기값으로 초기화 된다.
예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// register_vari.c
#include <stdio.h>
#include <time.h>
int main () {
clock_t start = clock ();
register long int i ;
long int last_for_num = 5000000000 ;
int sum = 0 ;
for ( i = 0 ; i < last_for_num ;) {
i ++ ;
sum += i ;
}
printf ( "sum = %d \n " , sum );
printf ( "i = %ld \n " , i );
clock_t end = clock ();
printf ( "time = %f \n " , ( double )( end - start ) / CLOCKS_PER_SEC );
return 0 ;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// non_reguster_vari.c
#include <stdio.h>
#include <time.h>
int main () {
clock_t start = clock ();
auto long int i ;
long int last_for_num = 5000000000 ;
int sum = 0 ;
for ( i = 0 ; i < last_for_num ;) {
i ++ ;
sum += i ;
}
printf ( "sum = %d \n " , sum );
printf ( "i = %ld \n " , i );
clock_t end = clock ();
printf ( "time = %f \n " , ( double )( end - start ) / CLOCKS_PER_SEC );
return 0 ;
}
1
2
3
4
5
6
7
8
9
# register_vari.c
sum = 55
i = 10
time = 10.227847
# non_reguster_vari.c
sum = 55
i = 10
time = 10.287730
Reference
C 프로그래밍 (김형근, 곽덕훈, 정재화 공저)
C 프로그래밍 강의 (방송통신대 - 이병래)
Tags:
auto ,
c ,
clang ,
c언어 ,
extern ,
lifetime ,
location ,
register ,
scope ,
static ,
storage ,
언어 ,
유효범위 ,
저장위치 ,
존속기간
Categories:
clang
Updated: 2025-12-d
Comments