자료실/C언어

C언어 - 변수의 생존기간과 저장 유형 지정자

자료수집중 2020. 6. 22.
반응형

변수는 생존기간에 따라서 분류하게 되면

정적 할당(static allocation)자동 할당(automatic allocation)으로 보통 나눌 수 있습니다.

 

정적 할당(static allocation)은 프로그램이 실행되는 동안 유지

자동 할당(automatic allocation)은 선언된 블록이 종료되면 같이 소멸됩니다.

 

전역 변수는 정적 할당입니다.

지역 변수는 기본적으로는 자동 할당입니다. 하지만 지역 변수도 정적 할당으로 사용할 수 있습니다.

바로 저장 유형 지정자(storage class specifier)를 통해서 변경이 가능합니다.

 

그러면 저장 유형 지정자를 한번 알아보겠습니다.

 

먼저 auto지정자입니다.

auto지정자는 기본적으로 지역 변수에 자동으로 할당됩니다. (자동 변수라고 합니다.)

생략해도 자동으로 할당되기 때문에 보통은 auto 지정자를 굳이 쓰지 않습니다.

 

int main(void) {
{
    auto int  num;
    int  num1; //앞에 auto를 적지 않아도 다른 지정자를 지정하지 않으면 자동으로 할당됩니다.
    return 0;
}

 

다음으로 static 지정자입니다.

static은 정적 변수를 사용할 수 있게 해 줍니다.

 

일반적인 auto변수는

void test_1();

int main(void) {
    test_1();
    test_1();
    test_1();
    test_1();
    return 0;
}

void test_1() {
    int num = 1;
    printf("%d \n", num);
    num += 10;
}

출력 후 num값에 10을 더해도 블록이 끝나는 순간 소멸하기 때문에 매번 함수를 호출할 때마다 초기값만 출력됩니다.

하지만 static으로 선언해주면 값이 완전히 변합니다.

void test_1();

int main(void) {
    test_1();
    test_1();
    test_1();
    test_1();
    return 0;
}

void test_1() {
    static int num = 1; //auto -> static으로 변경
    printf("%d \n", num);
    num += 10;
}

num의 값이 누적돼서 계산된 출력을 볼 수 있습니다.

static이 붙게 되면 처음에 한번 초기화를 하고 매번 호출마다 초기화하지 않습니다. 

static을 지역 변수에 붙여줌으로 정적 변수되고, 프로그램이 실행되는 동안 값을 유지합니다.

정적 변수가 되면 초기화를 하지 않으면 자동으로 0이 들어갑니다.

 

전역 변수는 이미 프로그램이 실행되는 동안 유지되는 변수이지만 static을 붙을 수 있습니다.

전역 변수는 static이 붙게 되면 외부에서 사용할 수 없게 됩니다.

static은 함수의 자료형 앞에도 붙일 수 있습니다. 전역 변수에 선언했을 때처럼 함수에 선언하면 선언된 함수를 외부에서 사용할 수 없습니다. 같이 보겠습니다.

// main.c

#include <Stdio.h> 

extern void test_1();  //extern은 외부에서 참조할 변수나 함수에 붙여줍니다.
extern void test_2();
extern int num1, num2, num3;
extern int num4;
int main(void) {
	printf("%d %d %d %d \n\n", num1, num2, num3, num4);
	test_1();
	test_1();
	test_1();
	test_1();

	test_2();
	test_2();
	test_2();
	test_2();

	return 0;
}

전역 변수와 함수에 static을 사용하기 위해선 extern을 같이 알아야 합니다.

extern지정자는 외부의 정의되어 있는 변수 또는 함수를 사용하기 위해서 선언하는 지정자입니다.

그러므로 초기화를 하지 않습니다.

원래 extern은 보통은 사용하지 않아도 됩니다. auto처럼 자동으로 생략되어있습니다.

위에 main.c는 전부 외부 함수 및 변수를 사용하므로 새로운 c파일을 한 개 더 추가해줍니다.

//test.c

#include <Stdio.h> 

int num1 = 1, num2 = 2, num3=3;
static int num4 = 4; //외부에서 사용 불가능

void test_1() {
	static int num = 1;
	printf("%d \n", num);
	num += 10;
}

// 외부에서 사용 불가능
static void test_2() {  
	static int num = 10;
	printf("%d \n", num);
	num += 100;
}

작성된 코드를 실행하면 에러가 발생합니다.

이유는 static으로 선언된 변수 num4와 함수 test_2()도 extern으로 선언했기 때문입니다.

static으로 선언된 변수와 함수는 외부에서 사용할 수 없습니다. 

사용하게 되면 "확인할 수 없는 외부 참조"라는 에러가 발생합니다. 

*에러를 확인하고 싶다면 extern을 붙여서 외부 선언을 해야 합니다.

그러므로 test.c에 static으로 선언된 num4test_2()는 main.c에서 사용이 불가능합니다.

 

마지막으로 register 지정자는 지역 변수에만 사용이 가능합니다.

register는 변수를 메모리 대신 cpu를 사용합니다. 그래서 속도가 빠릅니다.

그러다 보니 사용할 수 있는 개수가 제한되어있습니다. register를 선언한다고 모두 레지스터를 사용하지 않습니다.

그리고 register변수는 &(주소) 연산자를 사용할 수 없습니다. 레지스터는 주소가 없습니다.

 

속도가 빠르다 보니 보통 루프에 많이 사용합니다.

int main(void) {
    register int i;
    int sum = 0;
    for (i = 0; i <1000; i++) {
        sum += i;	
    }
    printf("%d\n", sum);
}

 

'자료실 > C언어' 카테고리의 다른 글

C언어 - 구조체  (0) 2020.06.27
C언어 - 배열  (0) 2020.06.23
C언어 - 지역변수, 전역변수  (0) 2020.06.22
C언어 - 함수(function)  (0) 2020.06.18
C언어 - break, continue, return  (0) 2020.06.17

댓글