본문 바로가기
IT/C and C++

[C] 전역변수와 지역변수란?

by 타이모리 2022. 12. 30.

전역변수와 지역변수는 꼭 짚고 넘어가야 할 내용 중 일부입니다.

어렵지는 않으니 꼭 읽어주셨으면 합니다.

목차


    전역변수와 지역변수가 뭔데?

    전역변수는 말 그대로 전역적으로 쓰이는 변수이며

    지역변수는 말 그대로 지역적으로 쓰이는 변수입니다.

     

    각 변수의 생성 위치에 따라 달라지는 소멸 위치가 전역 변수와 지역 변수의 차이를 결정짓습니다.

     

    전역변수와 지역변수를 알아보기 전에, 전역과 지역을 알아보자면

    간단하게 이야기해서 코드에서

    { }로 감싸진 부분은 모두 지역이며, 그 외를 전역이라고 부릅니다.

    어떤 코드를 감싸는 { }가 한 쌍이라도 존재하면 그 코드는 지역에 있는 코드입니다.

    저번 포스팅에서 이야기했던 함수의 기능부분은 { }로 싸여있었죠?

    { }로 감싸져 있기 때문에, 독립적인 기능이 가능했었습니다.

     

     

     

     

    전역변수란?


    전역변수는 { } 바깥에 생성된 변수입니다.

    중괄호 바깥에 생성된 전역변수는 결과적으로 프로그램이 끝날 때까지 유지됩니다.

    전역변수는 전역과 모든 지역에서 참조가 가능하기 때문에, 유지해야 하는 값들을 저장하고 싶을 때 자주 사용합니다.

    저번에는 반환값을 이용해서 함수에서 호출부로 영향을 끼치는 방법을 알아보았는데, (기억나지 않으시는 분은 아래!)

    2022.12.30 - [IT/C and C++] - [C] 함수란 무엇이고, 어떻게 사용하나요? (2/2)

     

    [C] 함수란 무엇이고, 어떻게 사용하나요? (2/2)

    저번 포스팅 [함수란 무엇이고, 어떻게 사용하나요? (1/2)] 에서는 함수의 선언과 관련된 부분을 주로 다루었습니다. 아래 포스팅을 참고해주세요. 2022.12.30 - [IT/C and C++] - [C] 함수란 무엇이고, 어

    timemory.tistory.com

    전역변수를 이용해도 함수에서 함수의 외부로 영향을 끼칠 수 있습니다.

    아래와 같은 코드에서는 전역변수를 이용한 함수 외부로의 영향을 나타냅니다.

    #include <stdio.h>
    
    int s = 0;
    
    void sum(int a, int b) {
    	s = a + b;
    }
    
    int main() {
    	sum(0, 1);
    	printf("결과 : %d", s);
    }

    sum 함수에서 매개변수로 전달된 0과 1을 더해 전역변수 s에 저장합니다.

    전역변수는 sum 함수와 main 함수 모두 참조가 가능하고, 값이 같기 때문에

    sum 함수에서 더한 값을 main 함수에서 참조하는 것이 가능합니다.

     

    그러나, 전역변수를 통한 함수 결과의 전달은 많은 프로그래머가 선호하지 않습니다.

    좋은 함수의 작성에서 함수는 독립적으로 행동할 수 있어야 합니다.

    그러나, 전역변수가 존재하는 함수는 독립적이 아니라 전역변수에 묶여 있기 때문에, 독립적인 행동이 불가능하게 됩니다.

    결과적으로 좋은 함수를 만들기 위해서는 전역변수의 활용을 최소화해야 합니다.

     

    지역변수란?


    지역에 선언된 변수를 모두 지역변수라고 부릅니다.

    지역변수의 생명은 선언되고 나서부터 선언된 블록에 한정되게 됩니다.

    지역변수를 참조할 수 있는 곳 또한 선언된 블록 내부에서만 가능합니다.

    선언된 블록이 종료되면 지역변수는 사라지게 됩니다.

    매개변수 또한 지역변수의 일종이고, 함수의 블록 { }가 지역변수의 효력이 미치는 곳이 됩니다.

     

    지역변수는 지역에서만 기능하기 때문에 이름의 중복이 가능하게 됩니다.

    #include <stdio.h>
    
    void printing() {
    	int x = 10;
    	printf("%d\n", x);
    }
    
    int main() {
    	int x = 1;
    	printf("%d\n", x);
    	printing();
    	printf("%d\n", x);
    }

    코드의 실행 결과를보시면 1, 10, 1 순서대로 나타나게 될 텐데

    같은 x의 이름을 썼음에도 불구하고, Printing 함수의 x 변수와 Main 함수의 x 변수가 독립적으로 존재해서 서로에게 영향을 끼치지 않는 것을 볼 수 있습니다.

    #include <stdio.h>
    
    void printing() {
    	int x = 0;
    	printf("%d", x);
    }
    
    int main() {
    	printing();
    	printf("%d", x); // Error!
    }

    보시다시피, 변수 x의 생명은 printing() 함수의 블록 { }에서 한정되기 때문에,

    printing 함수가 종료되고 나서 main 함수로 돌아왔을 때, x는 소멸하어 사용할 수 없게 됩니다.

    결과적으로, 변수 x가 존재하지 않으니 에러를 출력하게 됩니다.

     

    전역변수 vs 지역변수


    저는 처음 프로그래밍을 배우게 될 때, 

    "전역변수는 지역변수보다 오래 가는데, 전역변수가 훨씬 좋은 거 아닌가?"

    라는 생각을 했습니다.

    이는 틀린 생각입니다. 오히려 저는 지역변수의 활용을 적극적으로 추천합니다.

    전역변수의 남용은 다음과 같은 문제를 가지고 옵니다.

     

    1. 전역변수의 이름 문제

    전역변수는 프로그램 내내 유지되므로, 같은 이름을 가진 전역변수를 두 개 이상 선언해서는 안 됩니다. 지금은 전역변수의 개수가 적으니 큰 문제가 되지 않지만, 후에 코드가 매우 길어진다면 전역변수의 이름을 까먹고 중복으로 선언하게 될 수도 있습니다.

    2. 전역변수의 메모리 문제

    지역변수는 유효 범위를 벗어날 때, 메모리에서 해제되게 됩니다. 그러나 전역변수는 프로그램 실행 내내 유지되므로 차지하는 메모리의 해제가 이루어지지 않게 됩니다. 필수적으로 유지되어야 하는 전역변수가 아니라, 일회용으로 쓰일 전역변수는 쓸모가 없어지면 말 그대로 쓸모없는 메모리가 되어 자리를 차지하는 변수가 됩니다. 지금이야 기기의 성능이 매우 좋아져 큰 상관을 하지 않는다고 하더라도, 언젠가는 프로그래머의 발목을 붙잡을 수 있습니다.

     

    따라서 저는 전역변수는 필요할 때를 제외하고는 쓰지 않는 연습을 하는 것을 추천해 드립니다.

     

    전역변수와 지역변수는 이름 중복이 가능합니다.

    그러나, C언어에서는 전역변수와 지역변수의 이름 중복이 되었을 때, 지역변수의 블록 내부에서는 무조건 지역변수만을 참조할 수 있으므로 전역변수를 사용할 수 없게 됩니다.

    (C++부터는 ::을 이용해서 전역변수에 접근할 수 있습니다.)

    #include <stdio.h>
    
    int a = 0;
    int main() {
    	int a = 10;
    	printf("지역일까 전역일까? : %d", a);
    }

    10이 출력됩니다

     

    마무리

    이번에는 전역변수 및 지역변수에 관하여 공부해보았습니다.

    슬슬 기본적인 C의 내용이 끝나가는 듯합니다.

    앞으로는 훨씬 다양한 내용의 포스팅이 될 것 같군요.

    그럼, 다음 포스팅으로 넘어가 보도록 하겠습니다.

    댓글