78.3 extern으로 다른 소스 파일의 전역 변수 사용하기

이번에는 소스 파일이 여러 개로 분리되어 있을 때 전역 변수를 사용하는 방법입니다. 다음 내용을 프로젝트 디렉터리에 print.c로 저장하세요(파일은 GitHub 저장소의 Unit 78/78.3 폴더에 들어있습니다).

print.c

#include <stdio.h>

int num1 = 10;

void printNumber()
{
    printf("%d\n", num1);    // 전역 변수 num1의 값 출력
}

print.c 파일을 추가했으면 Visual Studio의 솔루션 탐색기 창에서 소스 파일을 클릭하고 마우스 오른쪽 버튼을 누릅니다. 팝업 메뉴가 나오면 추가(D) > 기존 항목(G)...를 클릭한 뒤 print.c를 선택하고 추가(A) 버튼을 클릭합니다.

이제 main 함수가 있는 소스 파일입니다. 다음 내용을 프로젝트 디렉터리에 main.c로 저장하세요.

main.c

#include <stdio.h>

int main()
{
    printf("%d\n", num1);    // 전역 변수 num1의 값 출력. 컴파일 에러

    return 0;
}

컴파일 결과

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

main 함수에서 전역 변수 num1의 값을 출력하고 있습니다. 하지만 컴파일을 해보면 num1이 선언되지 않은 식별자라고 나옵니다. 분명 print.c 파일에 전역 변수가 선언되어 있는데 말이죠.

다른 소스 파일(외부)에 선언된 전역 변수를 사용할 때는 extern 키워드를 사용합니다.

  • extern 자료형 전역변수;

main.c 파일의 내용을 다음과 같이 수정하여 실행해보세요(파일은 GitHub 저장소의 Unit 787/78.3 폴더에 들어있습니다).

main.c

#include <stdio.h>

extern int num1;    // 다른 소스 파일(외부)에 있는 전역 변수 num1을 사용

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

    return 0;
}

실행 결과

10

프로그램을 실행해보면 print.c에서 선언한 전역 변수의 값 10이 출력됩니다. 다른 소스 파일에 선언된 전역 변수를 사용하려면 extern 뒤에 자료형과 전역 변수의 이름을 지정해주면 됩니다.

extern int num1;    // 다른 소스 파일(외부)에 있는 전역 변수 num1을 사용

이처럼 다른 소스 파일에 선언된 전역 변수도 extern을 통하여 사용할 수 있으므로 소스 파일이 여러 개이면 전역 변수의 범위는 프로그램 범위입니다.

그림 78-3 extern으로 다른 소스 파일에 선언된 전역 변수 사용

여기서 주의할 점은 전역 변수 선언 없이 extern int num1;만 지정하면 컴파일(링크) 에러가 발생한다는 것입니다. 즉, extern int num1;은 전역 변수가 파일 외부에 있다는 것을 표시만 할 뿐 전역 변수 자체를 선언하지는 않습니다.

지금까지 전역 변수에 대해 배웠습니다. 전역 변수는 소스 코드의 모든 곳에서 접근할 수 있다는 점, extern은 전역 변수가 외부에 있다는 것을 표시만 할 뿐, 전역 변수를 선언하지 않는다는 점만 기억하면 됩니다.

참고 | extern으로 다른 소스 파일의 함수 사용하기

extern은 전역 변수뿐만 아니라 함수에도 사용할 수 있습니다.

  • extern 반환값자료형 함수이름(매개변수자료형);

먼저 print.c 파일에 printNumber 함수가 있습니다.

print.c

#include <stdio.h>

int num1 = 10;

void printNumber()
{
    printf("%d\n", num1);
}

여기서 extern void printNumber();와 같이 지정해주면 다른 소스 파일(외부)에 있는 함수를 사용할 수 있습니다.

main_extern_function.c

#include <stdio.h>

extern void printNumber();    // 다른 소스 파일(외부)에 있는 함수 printNumber를 사용

int main()
{
    printNumber();    // printNumber 호출

    return 0;
}

사실 extern을 붙이지 않고 함수 원형만 선언해도 다른 소스 파일에 있는 함수를 사용할 수 있습니다.

main_function_prototype.c

#include <stdio.h>

void printNumber();    // 함수 원형을 선언하여 다른 소스 파일(외부)에 있는 함수 printNumber를 사용

int main()
{
    printNumber();    // printNumber 호출

    return 0;
}
참고 | 같은 파일 안에서 extern 사용하기

전역 변수를 사용하려면 함수보다 먼저 선언해야 합니다. 만약 전역 변수가 함수 아래에 선언되면 컴파일 에러가 발생합니다.

global_variable_error.c

#include <stdio.h>

int main()
{
    printf("%d\n", num1);    // 컴파일 에러. 변수를 찾을 수 없음

    return 0;
}

int num1 = 10;    // 전역 변수를 함수 아래에 선언

컴파일 결과

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

이때는 전역 변수를 사용하고자 하는 함수 위에 extern으로 변수가 선언되어 있다는 것을 미리 알려주면 됩니다. 즉, extern은 다른 파일에 있는 전역 변수뿐만 아니라 같은 파일 안에 있는 전역 변수에도 사용할 수 있습니다.

global_variable_extern.c

#include <stdio.h>

extern int num1;    // 변수 num1이 선언되어 있다는 것을 미리 알려줌

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

    return 0;
}

int num1 = 10;    // 전역 변수를 함수 아래에 선언

실행 결과

10

물론 extern은 같은 파일 안에 있는 함수에도 사용할 수 있지만 함수 원형을 선언하는 것보다 입력해야할 글자가 많으므로 잘 사용하지 않는 방법입니다.