78.2 전역 변수 선언하기

이제 전역 변수를 선언해보겠습니다. 전역 변수는 함수 바깥에서 선언합니다. 다음 내용을 소스 코드 편집 창에 입력한 뒤 실행해보세요(파일은 GitHub 저장소의 Unit 787/78.2 폴더에 들어있습니다).

main.c

#include <stdio.h>

int num1 = 10;    // 전역 변수 선언 및 값 초기화

void printGlobal()
{
    printf("%d\n", num1);    // 20: main 함수에서 저장한 값이 계속 유지됨
}

int main()
{
    printf("%d\n", num1);    // 10: main 함수에서 전역 변수 num1의 값 출력

    num1 = 20;    // 전역 변수 num1에 20 저장

    printGlobal();    // 20: printGlobal 함수에서 전역 변수 num1의 값 출력

    return 0;
}

실행 결과

10
20

#include 아래에 int num1 = 10;과 같이 변수가 선언되어 있습니다. 이처럼 전역 변수는 함수 안이 아닌 함수 바깥에 선언합니다.

num1은 함수 블록 바깥에 선언되어 있으므로 모든 함수에서 값을 가져오거나 저장할 수 있습니다. 또한, 파일 자체에 변수가 선언되어 있으므로 변수의 범위는 파일 범위입니다.

그림 78-2 파일과 전역 변수의 범위

이제 각 함수에서 전역 변수 num1을 사용해보겠습니다. 먼저 main 함수에서 num1의 값을 출력해보면 10이 나옵니다. 그리고 num1에 20을 저장합니다.

int main()
{
    printf("%d\n", num1);    // 10: main 함수에서 전역 변수 num1의 값 출력

    num1 = 20;    // 전역 변수 num1에 20 저장

printGlobal 함수에서 num1의 값을 출력해보면 main 함수에서 저장한 20이 출력됩니다.

    printGlobal();    // 20: printGlobal 함수에서 전역 변수 num1의 값 출력

    return 0;
}

즉, 전역 변수는 모든 함수에서 접근할 수 있으며 한 번 저장한 값이 계속 유지됩니다.

void printGlobal()
{
    printf("%d\n", num1);    // 20: main 함수에서 저장한 값이 계속 유지됨
}

이번에는 전역 변수의 초깃값에 대해 알아보겠습니다. 다음 내용을 소스 코드 편집 창에 입력한 뒤 실행해보세요.

global_variable_initialized_zero.c

#include <stdio.h>

int num1;    // 전역 변수는 초깃값을 지정하지 않으면 0으로 초기화됨

int main()
{
    printf("%d\n", num1);    // 0

    return 0;
}

실행 결과

0

전역 변수는 초깃값을 지정하지 않으면 0으로 초기화됩니다. 이 부분은 초깃값을 지정하지 않으면 쓰레기 값이 들어가는 지역 변수와는 다른 점입니다. 그리고 전역 변수는 프로그램이 시작될 때 생성 및 초기화되고 프로그램이 끝날 때 사라집니다.

참고

역 변수는 반환값이나 매개변수를 통하지 않고 손쉽게 사용할 수 있어서 모든 변수를 전역 변수로 선언하면 좋겠다는 생각이 들텐데요. 아쉽게도 좋은 방법이 아닙니다.

전역 변수는 꼭 필요한 부분에만 사용해야 하며 전역 변수를 무분별하게 사용했을 때 발생하는 문제점은 다음과 같습니다.

  • 프로그램이 커지다 보면 어떤 함수가 전역 변수의 값을 바꾸는지 알기 어려워집니다. 이렇게 되면 유지보수도 힘들어지고 눈에 잘 띄지 않는 버그가 생기기 쉽습니다.
  • 지역 변수와 전역 변수의 이름이 겹칠 가능성이 커지고 의도하지 않은 결과가 나올 수 있습니다. 지역 변수와 전역 변수의 이름이 같을 때는 현재 블록의 변수를 우선으로 접근합니다.

duplicate_variable_name.c

#include <stdio.h>

int num1 = 10;    // 전역 변수의 이름은 num1

int main()
{
    int num1 = 20;    // 지역 변수의 이름도 num1

    {
        int num1 = 30;           // 블록 안에 선언된 지역 변수의 이름도 num1
        printf("%d\n", num1);    // 30: 현재 블록의 변수를 사용
    }

    printf("%d\n", num1);    // 20: 현재 블록의 변수를 사용

    return 0;
}

실행 결과

30
20
참고 | 헝가리안 표기법과 전역 변수

Windows API를 사용한 소스 코드에서 헝가리안 표기법을 자주 볼 수 있습니다. 변수의 이름에 자료형이나 주요 정보를 접두어로 함께 표기하는 방식입니다. 다음은 헝가리안 표기법의 간단한 예입니다.

표 78-1 헝가리안 표기법
자료형, 데이터 형태, 변수 종류 접두어
short, int n nIndex
long l lCount
float f fDistance
NULL로 끝나는 문자열 sz szFilename
포인터 p pNext, pCurr
전역 변수 g g_num1

특히 전역 변수는 g_num1과 같이 앞에 g_를 붙입니다. 하지만 최근에는 개발 도구 편집기의 기능이 좋아진 점도 있어서 헝가리안 표기법을 잘 사용하지 않는 추세입니다. 다른 사람의 코드를 볼 때 참고해주세요.