본문 바로가기
개발 Tools/C_개념

C 기억 클래스 (storage class, auto, static, extern, register)

by 전컴반 2022. 6. 15.
반응형
auto 

 

자동 변수의 정의는 함수 안에서 선언하는 지역 변수들은 모두 auto변수다.

auto변수는 함수가 호출되어 실행될 때만 메모리(stack)가 할당되고 함수가 끝나면 메모리를 회수한다. 이때 초기화를 꼭 해줘야 한다. 아니면 쓰레기 값이 들어갈 수도 있다.

중요한 건, 실행될 때이다. 디버깅할 때 코드를 쭉 훑어보는데 선언이 돼 있지만 생성되진 않고 해당 코드가 실행될 때 생성된다. 

 

쉽게 말하면 우리가 흔히 사용하고 있는 변수가 다 auto변수다. auto를 생략하여 사용할 수 있다.

예를 들어 아래 선언한 두 변수는 동일하다.

 

int main(void) {
    auto int var_auto = 0;
    int var_non_auto = 0;
}

 

main문이 실행되고 종료되면 var_auto, var_non_auto는 소멸된다. 기존에 가지고 있던 값을 잃어버린다는 의미다.

 

 

static 

 

정적 변수라고 불리는데 auto와 반대로 함수가 끝나도 메모리(데이터 영역)가 회수되지 않고 정보가 남아있는 변수다. 

auto와 큰 차이라고 하면, auto는 코드가 실행될 때, 생성되지만, static은 프로그램 생성과 동시에 생성된다.

특별히 초기화하지 않아도 0으로 초기화된다.

 

예를 보면 좀 더 이해가 쉬울 것이다.

 

#include <stdio.h>

void count(void) {
	int cnt = 0; // 호출 후 실행 시 메모리 할당됨
	static static_cnt = 0; // 프로그램 생성시 메모리 할당됨

	cnt++;
	static_cnt++;
	printf("auto cnt = %d, static cnt = %d\n", cnt, static_cnt);
}

int main(void)
{
	for (int i = 0; i <= 3; i++) {
		count();
	}
	return 0;
}

 

보면 auto는 함수가 호출될 때마다 생성과 소멸을 반복하지만 static은 계속 정보를 가지고 있다. 즉, auto는 메모리를 매번 새로 할당되고 static은 한 명 할당하면 계속 유지된다.

 

 

extern

 

외부 변수로 static은 하나의 프로그램에서 전역 변수로도 사용할 수 있지만 다른 프로그램에서는 사용하지 못한다. 

즉, 여러 프로그램(파일)에 영향을 주기 위해선 extern을 선언하여 사용한다. 컴파일러에게 외부 파일에서 정의된 전역 변수를 사용한다고 알려줘야 한다. 메모리의 데이터 영역에 할당된다

 

아래에 하나의 프로그램을 실행한다고 했을 때, func()를 호출하는데 func()가 다른 파일로 존재한다 하자

 

// 파일 1
#include <stdio.h>
void func(void);

int data;
int main(void)
{
	data = 9;
	printf("before call = %d\n", data);
	func();
	printf("after call = %d\n", data);
	return 0;
}

 

func를 호출하면 해당 파일로 이동하여 동작하는데 해당 파일에는 data에 대한 선언이 없다면 에러가 뜬다. 변수 data는 main 프로그램에만 존재하고 func() 프로그램에서는 효력이 없다. 그래서 extern int data를 선언해줘야 한다. 

 

+ data 변수 선언할 때 static int data 하면 안 된다. 이렇게 되면 해당 파일에서만 전역 변수로 사용된다. 다른 파일에서는 전역 변수로 사용할 수 없다. static을 선언하고 사용하면 error LNK2001 뜬다. 

 

// 파일2
#include <stdio.h>

extern int data;
void func(void) {
	data = 10;
	printf("call func = %d\n", data);
	data = 20;
}

 

이렇게 전역 변수로 선언된 data를 사용하겠다고 extern int data라고 선언하고 사용한다. 

 

 

두 파일을 링킹 하여 빌드하고 실행하면 위와 같은 결과가 나온다.

 

+ 프로젝트 컴파일하는 방법은 프로젝트에서 "빌드"옵션에서 "Workspace 빋드"를 누르고 빌드되면 실행한다.

난 프로젝트 이름이 "Workspace"다 본인 프로젝트 이름에 따라 다르게 나올 것이다. 

 

 

register 

 

간단히 말하면 CPU 내부 레지스터에 저장하는 것이다. 속도가 굉장히 빠르지만 용량에 제한이 있어서 2~3개 정도 사용한다. 또한 크기도 제한이 있어서 int, char형 밖에 사용할 수 없다. 하지만 요즘은 크게 사용하지 않는다. 

 

register int i;
for(i = 0;i < 100; i++)
	sum += i;

 

반응형

댓글