변수 영역

컴퓨터 프로그래밍에서 **변수 영역**은 변수가 유효성을 갖는 영역을 가리킨다. 프로그램은 영역을 벗어난 변수를 가리킬 수 없다.

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

## 종류

### 전역

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

### 모듈 영역

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

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

### 파일 영역

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

### 함수 영역


```python
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
```


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

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

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

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

### 블록 영역


```c
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;
}
```


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

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

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

### 표현식 영역

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

## 정적 영역 규칙

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

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

## 동적 영역 규칙

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

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

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