C 언어(21) - 변수의 종류와 생존 시간

C 언어 강의, 변수의 종류, 생존 시간

Featured image

🔚 짧게 하는 복습

✅ 1. 프로그램의 실행 과정을 안다.

✅ 2. 전처리 과정에 대해 자세히 안다.

✅ 3. 라이브러리 함수와 헤더 파일을 다룰 줄 안다.(과제를 통해 이해하자)

혹시 기억이 안 난다면, 다시 돌아가자


우리는 이미 메모리 구조 및 스택 프레임에 대해 깊게 다룬 기억이 있다.( 모른다면)

여기서 함수를 호출했을 때, 함수 간의 변수 이름이 같아도 다른 공간을 할당받고 각각 다른 값을 저장한다는 것을 알 수 있었다.

그런데 오늘은 이뿐만 아니라 특별한 경우에 대해서 더 다루어 보겠다.


지역 변수란?

우리가 이때까지 int main을 포함해서 모든 함수에서 변수를 선언하곤 했는데, 지금까지 한 모든 변수는 지역 변수라는 종류의 변수이다.

여기서 함수 뿐만 아니라, {}로 싸인 블록 안에서 일반적인 방법으로 선언(자료형 변수 이름)된 변수도 지역 변수라 말한다.

예를 들어,

#include<stdio.h>

void change1(){
    int n = 5; //지역 변수
}
int main() {
    int n = 4; //지역 변수

    change1();
    if(n == 4){
        int answer1 = 4; //지역 변수
        printf("answer = %d", answer1);
    }
    else if(n == 5){
        int answer2 = 4; //지역 변수
        printf("answer = %d", answer2);
    }

    return 0;
}

위의 코드에서 선언된 모든 변수는 지역 변수이다.

int n = 5는 change()라는 함수 안에서, int n = 4는 main 함수 안에서, answer1, 2는 각각 if와 else if 블록 안에서 선언되었기 때문이다.

지역 변수의 가장 큰 특징은 선언된 블록이나 함수 안에서만 유효하다는 점이다.

즉, 저번에 본 것처럼 change()라는 함수에서 호출된 n은 main 함수에서 사용할 수 없다. (메모리 영역 차이)

또한, 블록 내에서 선언된 answer1, 2 역시 블록을 제외한 main 함수에서 사용할 수 없다. (메모리 구조와 무관하게, 그냥 그렇게 정의함)

이를 생존 기간혹은 유효 범위이라고 한다.(거의 같은 의미이다.)

다시 한번 말해, 다른 함수를 호출했을 때 다른 스택 프레임에 저장되는 것과는 달리,

answer1, 2, n은 모두 main의 스택 프레임에 저장되지만 변수 유효 범위 차이 때문에 참조가 되지 않는다.


전역 변수(global 변수)

전역 변수는 지역 변수와 다르게 모든 영역에서 참조가 가능한 변수이다.

선언 방법은, 정의된 모든 함수보다도 위에 선언하면 된다. (사실 함수 정의들 사이에 선언해도 되지만, 관습적으로 그렇게 하지 않는다.)

또한, 전역 변수는 초기화가 없으면 0 혹은 NULL으로 초기화가 자동으로 된다.

위 코드를 실행해보면 어느 블록, 어느 함수에서 호출을 시켜도 변수가 유효한 것을 알 수 있다.

이는 전역 변수가 저장되는 영역은 지역 변수와는 다르기 때문인데, 저번에 봤던 메모리 구조가 기억나는가?

여기서 지역 변수는 stack 영역에 저장되는 반면에, 전역 변수는 data 영역에 저장된다.

data 영역은 함수 호출이 끝나면 할당이 해제되는 stack과는 다르게 정적인 공간이다.


정적 변수(static 변수)

마지막으로 정적 변수가 있다. 정적 변수는 함수 안에서 호출되었지만, 생존 기간이 함수 종료가 아니라 프로그램 종료인 변수들이다.

즉, 전역 변수처럼 프로그램이 종료될 때까지 유효한 것이다.

선언 및 초기화는 지역 변수 선언처럼 하는데, 그 앞에 static이라는 단어를 붙여주면 된다.

다만 한 번만 선언 및 초기화가 이루어지고, 함수에서 선언되었기에 함수 호출을 통해서만 참조할 수 있다.

무슨 말인지 직접 코드를 보자,

직접 보면 알겠지만, static int n = 5;는 처음 선언될 때만 사용되고 그 뒤 호출부터는 의미가 없다.

그리고 지역 변수처럼 함수 밖에서의 직접 참조는 불가능하다.

가장 중요한 점은 함수 호출이 종료돼도, 값이 저장된다는 것이다.

이는 정적 변수 역시 전역 변수처럼 data 영역에 저장되기 때문이다.


정리

  전역 변수 지역 변수 정적 변수
생존 기간 프로그램 종료까지 함수 종료까지 프로그램 종료까지
유효 범위 코드 전체 함수 혹은 블록 내부 함수 내부

📖 오늘의 핵심(다 알기 전까지는 넘어가지 말자❗)

✅ 1. 지역 변수, 전역 변수, 정적 변수의 정의와 생존 기간, 유효 범위 차이를 안다.

⚠️ 전역 변수와 정적 변수의 남용을 줄이자. 코드가 스파게티가 될 수 있다.

💣 과제, 없음.