{{위키데이터 속성 추적}}
{{출처 필요|날짜=2015-11-28}}
[[컴퓨터 프로그래밍]]에서 '''변수 영역'''은 변수가 유효성을 갖는 영역을 가리킨다. 프로그램은 영역을 벗어난 변수를 가리킬 수 없다.

변수 영역을 지정하는 규칙은 크게 '''정적 영역 규칙'''과 '''동적 영역 규칙'''으로 나뉜다. 정적 영역 규칙을 따르는 언어에서는 변수의 유효 영역이 [[컴파일 타임]]에 결정되며, 동적 영역 규칙은 [[런타임|실행 시간]]에 결정된다. 대부분의 현대 언어는 정적 영역 규칙을 따르지만, 매크로를 컴파일할때는 동적 영역 규칙을 따르기도 한다.

== 종류 ==

=== 전역 ===

가장 간단한 변수 영역은 소스 코드 상의 모든 곳에서 사용할 수 있는 [[전역 변수]]이다. 전역 변수는 많은 언어에서 나쁜 관습으로 취급되지만, 그런 경우에도 함수명이나 클래스 명은 대부분 전역에서 접근할 수 있다. [[이름공간]]을 사용하면 전역 영역에서 변수나 함수명이 충돌하는 것을 막을 수 있다.

=== 모듈 영역 ===

[[모듈라]]나 [[파이썬]]과 같이 [[모듈성 (프로그래밍)|모듈]]을 지원하는 프로그래밍 언어에서는 모듈 단위 변수를 선언할 수 있다. 이 변수들은 같은 모듈 안에서만 접근할 수 있으며, 모듈 밖에서는 변수를 볼 수 없다.

[[C++]] 등 모듈 개념을 지원하지 않는 일부 [[객체 지향 프로그래밍|객체 지향]] 언어에서는 [[클래스]]가 모듈 영역의 역할을 대신하기도 한다. 모듈과 객체의 개념을 모두 지원하는 파이썬의 경우 모듈 단위 영역과 클래스 단위 영역을 둘 다 지원한다.

=== 파일 영역 ===

파일 영역은 [[C (프로그래밍 언어)|C]]와 [[C++]] 및 그 유사 언어에서만 지원하는 개념이다. 이런 언어에서는, 소스 파일의 최상위에서 선언된 변수나 함수는 해당 파일 전체에서 접근할 수 있고, 다른 파일에서는 접근할 수 없다. 파일 영역은 보다 원시적인 형태의 모듈 영역으로 여겨진다.

=== 함수 영역 ===

<syntaxhighlight lang=python style="float:right;margin-left:1em">
def square(n):
  return n * n

def sum_of_squares(n):
  total = 0
  i = 0
  while i <= n:
    total += square(i)
    i += 1
  return total
</syntaxhighlight>

대부분의 프로그래밍 언어는 함수 내에서만 유효한 [[지역 변수]]를 제공한다. 함수 영역을 사용하는 지역 변수는 함수가 반환되면 더 이상 사용할 수 없다. 오른쪽의 파이썬 코드에서 변수 <code>n</code>은 함수의 인자로, 함수 밖에서는 사용할 수 없다. 또한 변수 <code>total</code>는 인자는 아니지만 함수 내에서 선언된 지역 변수로, 마찬가지로 함수 밖에서는 사용할 수 없다.

정적 영역 규칙에서는 함수가 다른 함수를 호출할 경우 변수는 영역 밖으로 벗어나게 되며, 해당 변수를 사용할 수 없게 된다. 그러나 동적 영역 규칙에서는 다른 함수가 호출되더라도 변수가 여전히 사용 가능하며, 함수가 최종적으로 종료될 때 비로소 변수가 영역 밖으로 벗어나게 된다. 동적 영역 규칙은 이런 특성으로 인해 소스 코드 단위에서 변수의 사용 가능 여부를 분석할 수 없고, 실행 시의 동작에 따라 변수의 사용 가능 여부가 바뀌게 된다. 이것은 종종 찾아내기 힘든 버그를 만들어낼 수 있기 때문에, 현대 프로그래밍 언어들은 대부분 정적 영역 규칙을 사용한다.

정적 영역 규칙의 경우, 함수 <code>square</code>의 인자 <code>n</code>과 함수 <code>sum_of_squares</code>의 인자 <code>n</code>은 이름은 같지만 서로 별개의 영역에 선언되어 있다. 따라서 두 변수는 완전히 독립되어 서로 어떤 영향도 끼치지 않는다.

만약 오른쪽 코드에서 동적 영역 규칙이 사용될 경우, <code>sun_of_squares</code>의 인자 <code>n</code>은 <code>square</code>의 인자 <code>n</code>과 겹치게 된다. 이 경우 이름 마스킹이 일어나, 기존의 <code>n</code> 변수를 가렸다가, 함수가 반환될 때 다시 원래 변수를 가리키게 될 것이다.

=== 블록 영역 ===

<syntaxhighlight lang=C style="float:right;margin-left:1em">
unsigned int sum_of_squares(unsigned int n) {
  unsigned int ret = 0;
  for(unsigned int i = 0; i <= n; ++i) {
    unsigned int n_squared = i * i;
    ret += n_squared;
  }
  return ret;
}
</syntaxhighlight>

[[알골 (프로그래밍 언어)|알골]]과 그의 자손인 [[C (프로그래밍 언어)|C]], 그리고 그에 영향을 받은 많은 현대 언어들은 블록 단위 지역 변수를 지원한다.

예를 들어 오른쪽의 C 코드에서, 변수 <code>i</code>는 <code>for</code> 문 안에서만 유효한 루프 변수이다. 또한 <code>n_squared</code>는 블록 안에서 선언된 변수로, 블록 안에서만 유효하다. 한편 이 블록은 함수 안에 들어 있으므로, 블록 바깥에서 선언된 변수인 <code>ret</code>는 블록 안에서도 사용 가능하다. 블록 영역은 여러 개의 블록 안에서 선언된 변수들이 서로 간섭하지 않도록 하여, 에러의 가능성을 줄여 준다.

블록 영역 변수는 오른쪽 코드에서처럼 루프나 조건문에서 유용하게 사용할 수 있지만, 변수 영역을 제한하기 위한 용도로 블록을 따로 선언하는 것도 가능하다.

=== 표현식 영역 ===

대부분의 [[함수형 프로그래밍]] 언어는 <code>let</code> 문을 지원한다. 예를 들어 [[ML (프로그래밍 언어)|ML]]에서 <code>let val x = f() in x * x end</code> 와 같은 표현식에서, 변수 x는 이 표현식 안에서만 유효하다. 이와 같은 표현식은 <code>f()</code>를 두번 호출하는 낭비를 막기 위해 쓰일 수 있다.

== 정적 영역 규칙 ==

''정적 영역 규칙''은 변수의 유효 영역이 소스 코드 상의 구조를 바탕으로 결정된다. 이로 인해 변수 영역은 실행 시간의 [[호출 스택]]이나 언어의 구현에 독립적이다. 이런 규칙에서는 변수의 유효 영역을 소스 코드만 보고 알아낼 수 있으므로, ''문법적 영역 규칙''(lexical scoping rule)이라고도 한다. 정적 영역 규칙은 [[알골 (프로그래밍 언어)|알골]]과 그의 자손인 [[C (프로그래밍 언어)|C]], 그리고 대부분의 현대 프로그래밍 언어에서 사용된다. 이 규칙은 [[구조적 프로그래밍]]에서 변수의 수명 주기를 쉽게 알아볼 수 있게 하여 프로그램의 [[모듈성 (프로그래밍)|모듈성]]을 증가시킨다.

함수를 값으로 반환할 수 있는 [[함수형 프로그래밍]] 언어의 경우 정적 영역 규칙은 좀더 복잡하다. 함수를 선언할 당시 자신의 바깥 영역에 있는 변수를 사용할 수 있기 때문이다. 이 경우 내부에 중첩된 함수는 함수 코드와 함수 선언 시의 변수 환경을 같이 갖고 있게 되며, 이런 자료구조를 [[클로저 (컴퓨터 과학)|클로저]]라고 부른다.

== 동적 영역 규칙 ==

''동적 영역 규칙''을 사용하는 언어는 대개 호출 스택에 변수의 바인딩이 포함되어 있다. 변수가 선언될 때 스택의 맨 위에 각 변수가 선언되며, 프로그램의 흐름이 변수 영역을 빠져나갈 때 스택의 맨 위가 팝된다. 호출 스택은 [[런타임]]에만 동작하므로, 컴파일 타임에는 동적 영역 규칙을 실행할 수 없다.

동적 영역 규칙을 사용하는 언어로는 [[펄]], [[커먼 리스프]] 등이 있다. 또한 [[C 언어 전처리기]]를 비롯, 대부분의 언어에서 [[매크로 (컴퓨터 과학)|매크로]]의 변수 영역은 동적 영역 규칙과 유사한 규칙을 따른다.

[[분류:프로그래밍 언어 개념]]