78 전역 변수 사용하기

지금까지 함수 안에서 선언하는 지역 변수를 사용했습니다. 지역 변수는 선언된 함수 안에서만 사용할 수 있고 다른 함수에서는 사용할 수 없습니다. 왜냐하면 C 언어는 범위에 따라 변수의 접근을 제한하기 때문입니다. 따라서 지역 변수는 함수 안에서만 유효합니다.

여기서 함수 범위는 함수가 시작하는 중괄호와 끝나는 중괄호 사이를 말합니다.

void hello()
{    // 함수 범위의 시작

    int num1;    // 지역 변수. hello 함수 안에서만 사용할 수 있음

}    // 함수 범위의 끝

그럼 프로그램 전체에서 공유해야 하는 값은 어떻게 할까요? 지역 변수는 함수 안에서만 사용할 수 있어서 적합하지 않습니다. 이럴 때는 전역 변수를 쓰는데 전역 변수는 범위에 제한을 받지 않고 모든 범위에서 사용할 수 있는 변수를 말합니다.

이번에는 변수의 범위에 대해 자세히 알아보고 전역 변수를 선언하는 방법, 다른 소스 파일에 있는 전역 변수를 사용하는 방법을 알아보겠습니다.

78.1 변수의 범위 알아보기

C 언어에서 중괄호로 묶은 부분을 블록(block)이라 부릅니다. 즉, if, for, switch, while, do while, 함수에 사용한 중괄호가 블록입니다. 또한, 그냥 중괄호만으로 이루어진 것도 블록입니다(단, 배열, 구조체, 공용체 등을 초기화 할 때 사용하는 중괄호는 블록이 아닙니다).

if (조건식)
{
    // if 조건문의 블록
}

for (초기식; 조건식; 변화식)
{
    // for 반복문의 블록
}

{
    // 그냥 중괄호만으로 이루어진 블록
}
void hello()
{
    // 함수의 블록
}

이제 블록 안에 변수를 선언해보겠습니다.

scope_error.c

#include <stdio.h>

int main()
{
    {
        int num1 = 10;       // 블록 안에 변수를 선언
    }

    printf("%d\n", num1);    // 컴파일 에러. 블록 바깥에서는 num1을 사용할 수 없음

    return 0;
}

소스 코드를 컴파일해보면 컴파일 에러가 발생합니다.

scope_error.c(9): error C2065: 'num1': 선언되지 않은 식별자입니다.

먼저 변수 num1은 중괄호로 묶인 블록 안에 선언되어 있습니다. 이때 블록 밖에서 num1을 사용하려고 하면 변수를 찾을 수 없기 때문에 컴파일 에러가 발생합니다. 즉, 변수는 선언된 블록(영역) 안에서만 사용(접근)할 수 있으며 이를 변수의 범위(scope)라고 합니다.

그럼 이번에는 main 함수에 변수를 선언하고 중첩된 블록 안에서 사용해보겠습니다.

scope.c

#include <stdio.h>

int main()
{
    int num1 = 10;    // main 함수 블록에 변수 선언

    {
        printf("%d\n", num1);    // 10: 현재 블록 바깥의 변수는 사용할 수 있음
    }

    return 0;
}

실행 결과

10

컴파일도 문제없고 실행을 해보면 변수 num1의 값이 잘 나옵니다. 여기서 변수 num1main 함수 블록에 선언되어 있고, printf가 있는 블록도 실제로는 main 블록 안에 있습니다. 따라서 변수가 선언된 블록 안에서 사용하는 것이 되므로 문제가 없습니다.

변수를 사용하는 입장에서 본다면 현재 블록 바깥에 선언된 변수를 사용할 수 있다는 뜻이 됩니다. 따로 이렇게 설명해서 생소해보이지만 사실 지금까지 일반적으로 사용하던 방식입니다.

int num1 = 10;

if (num1 > 5)
{
    printf("%d는 5보다 큽니다.\n", num1);    // if 조건문 바깥에 선언된 변수 num1을 사용
}

정리하자면 변수는 선언된 블록에 따라 사용할 수 있는 범위가 결정됩니다. 즉, 변수는 선언된 블록 안에서만 사용할 수 있고 블록 바깥에서는 사용할 수 없습니다.

그림 78-1 블록과 변수의 범위