[C++] 자유 변수, 레지스터 변수, 정적 변수 ft. 유효 범위

2022. 6. 27. 12:55♣ C++

이번 포스팅에선 유효 범위가 다른 3개의 변수에 대해 알아보겠습니다.

유효 범위(scope): 하나의 변환 단위(file) 내에서 해당 변수가 사용될 수 있는 범위

연결(linkage): 해당 변수를 사용할 수 있는 파일의 접근 가능 여부

* 외부 연결: 여러 변환 단위에서 사용 가능한 것을 말한다.

 

개발 환경 : VSCode, Windows 10

 

 

 

 

 

기본 개발 세팅은 다음과 같습니다.

#include <iostream>
#include <string.h>
#include <string>
using namespace std;

int main()
{
	return 0;
}

 

 

💥 알고 가야 하는 개념

[개념] 변환 단위란 무엇인가요?

[답변] C++에선 한 개의 파일(file)을 말합니다. 

 

 

 

 

 

📌 C++ 변수의 종류


C++에는 세 종류의 변수가 있습니다.

자동 변수, 레지스터 변수, 정적 변수. 이들은 각자의 유효 범위와 연결이 다릅니다. 사용자는 각 변수들의 특성을 활용하여 코드를 짜야 합니다.

 

 

1. 자동 변수(automatic variable)

: 블록 내에서 선언된 변수입니다. 함수의 매개 변수가 그 예시입니다. 블록 내에서만 유효하고 블록이 종료되면 메모리에서 없어집니다.

 

void automatic();

int main()
{
    int var = 10;
    cout << "main 함수 안의 var 값은 " << var << endl;
    automatic();
    if (var > 5){
        int var = 50;
        cout << "if문 안의 var 값은 " << var << endl;
    }
}

void automatic()
{
    int var = 100;
    cout << "함수 안의 var 값은 " << var << endl;
}

main()에서 선언된 var, if문에서 선언된 var, automatic() 함수에서 선언된 var.

모두 자동 변수이며, 해당된 블록 안에서만 작동함을 알 수 있습니다. 

 

 

결과

main 함수 안의 var 값은 10
함수 안의 var 값은 100
if문 안의 var 값은 50

 

 

 

 

 

2. 레지스터 변수(register variable)

: C언어에선 CPU 레지스터 메모리에 저장하는 변수였습니다. 하지만 C++로 넘어오면서 그냥 자동 변수를 의미하게 되었습니다. 

 

 

 

 

 

 

3. 정적 변수(static variable)

: 프로그램이 실행되는 내내 유지되는 변수입니다. 데이터 영역에 저장되고, 초기화되지 않으면 0으로 자동 초기화됩니다.

 

 

 

🎨 3-1. 연결을 가지지 않는 정적 변수

: static 키워드를 사용하여 정의합니다. 지역 변수 + 전역 변수

 

 

한 번만 초기화되고, 프로그램이 종료되어야 메모리에서 사라집니다.

해당 블록 내에서만 접근 가능합니다.

void Static_Func(void);

int main()
{
	for (int i=0; i < 10; i++)
    {
        Static_Func();
    }
	return 0;
}

void Static_Func(void)
{
	static int var = 10;
    cout << "현재 정적 변수 var의 값은 " << var << " 입니다." << endl;
    var++;
}

 

결과

현재 정적 변수 var의 값은 10 입니다.
현재 정적 변수 var의 값은 11 입니다.
현재 정적 변수 var의 값은 12 입니다.
현재 정적 변수 var의 값은 13 입니다.
현재 정적 변수 var의 값은 14 입니다.
현재 정적 변수 var의 값은 15 입니다.
현재 정적 변수 var의 값은 16 입니다.
현재 정적 변수 var의 값은 17 입니다.
현재 정적 변수 var의 값은 18 입니다.
현재 정적 변수 var의 값은 19 입니다.

함수가 종료된 후에도 var 값은 메모리에 남아있었습니다.

그렇기에 함수가 다시 호출되어도 변경된 var 값이 호출된 후 프로세스가 실행되었습니다.

 

 

 

 

 

🎨 3-2. 내부 연결을 가지는 정적 변수

: 유효 범위를 변환 단위(현재 파일)로 가집니다. 하나의 파일 내의 모든 블록에서 접근 가능합니다.

 

// 함수 밖에 선언합니다.
static 변수타입 변수명;

static int InnerStatic = 1;

 

 

이 경우, 어떤 블록에서든 접근이 가능합니다.

#include <iostream>
#include <string.h>
#include <string>
using namespace std;

static int InnerStatic = 1;

void Static_Func(void);

int main()
{
	cout << "InnerStatic은 main()에서도 유효합니다. : " << InnerStatic << endl;
    if (InnerStatic > 0){
        cout << "InnerStatic은 If문에서도 유효합니다. : " << InnerStatic << endl;
    }
    Static_Func();
	return 0;
}

void Static_Func(void)
{
    cout << "InnerStatic은 함수에서도 유효합니다. : " << InnerStatic << endl;
}

 

 

결과

InnerStatic은 main()에서도 유효합니다. : 1
InnerStatic은 If문에서도 유효합니다. : 1
InnerStatic은 함수에서도 유효합니다. : 1

 

 

 

 

🎨 3-3. 외부 연결을 가지는 정적 변수

: 유효 범위를 변환 단위로 가집니다. 다른 파일에서도 변수를 사용할 수 있습니다. 외부 연결을 가지므로 전역 변수/외부 변수라고도 합니다. 변수 정의는 한 파일에서만 하며, extern 키워드를 사용하여 접근합니다.

#include "변수가 있는 파일명"
extern 변수타입 변수명;

 

 

C++_2.cpp 파일

: 변수를 정의합니다.

#include <iostream>
#include <string.h>
#include <string>
using namespace std;

int OuterStatic = 0;

 

 

C++_1.cpp 파일

: extern 키워드를 이용하여 다른 파일에 있는 변수를 불러옵니다.

#include <iostream>
#include <string.h>
#include <string>
using namespace std;

#include "C++_range_2.cpp"
extern int OuterStatic;

void Static_Func(void);

int main()
{
	cout << "OuterStatic은 main()에서도 유효합니다. : " << OuterStatic << endl;
    if (OuterStatic > -1){
        cout << "OuterStatic은 If문에서도 유효합니다. : " << OuterStatic << endl;
    }
    Static_Func();
	return 0;
}

void Static_Func(void)
{
    cout << "OuterStatic은 함수에서도 유효합니다. : " << OuterStatic << endl;
}

 

 

결과

OuterStatic은 main()에서도 유효합니다. : 0
OuterStatic은 If문에서도 유효합니다. : 0
OuterStatic은 함수에서도 유효합니다. : 0

 

 

 

 

 

지금까지 자유 변수, 레지스터 변수, 정적 변수에 대해 알아보았습니다.

이들의 특성과 유효 범위는 각각 다르므로 알맞게 활용해야 합니다. 고생하셨습니다.