맨위로가기

지역 변수

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

지역 변수는 특정 블록 또는 함수 내에서만 유효한 변수를 의미하며, 프로그래밍 언어에서 변수의 스코프를 정의하는 중요한 개념이다. 지역 변수는 어휘적(정적) 스코프 또는 동적 스코프를 가질 수 있으며, 대부분의 언어는 어휘적 스코프를 사용한다. 어휘적 스코프는 변수가 선언된 블록 내에서만 변수를 사용할 수 있게 한다. 반면, 동적 스코프는 변수가 해당 블록과 해당 블록에서 호출되는 모든 함수에서 유효하게 한다. C/C++, Java, Perl, Ruby 등 다양한 프로그래밍 언어에서 지역 변수를 지원하며, 각 언어마다 지역 변수를 정의하고 사용하는 방식에 차이가 있다. 특히 C/C++에서는 정적 지역 변수를 사용하여 함수 호출 간에 값을 유지할 수 있으며, Java는 정적 지역 변수를 지원하지 않는다. Perl은 동적 및 사전적 지역 변수를 모두 지원하며, Ruby는 정적 범위 지역 변수를 기본으로 사용한다.

더 읽어볼만한 페이지

  • 변수 (컴퓨터 과학) - 멤버 변수
    멤버 변수는 객체 지향 프로그래밍에서 객체의 속성을 저장하고 관리하며 객체의 상태를 나타내는 변수로, 지역 변수와 달리 객체의 생명 주기와 함께 값을 유지한다.
  • 변수 (컴퓨터 과학) - 정적 변수
    정적 변수는 프로그램 실행 시간 동안 값을 유지하며, C 언어에서 `static` 키워드로 정의되어 함수 호출 간에 값을 유지하고, 객체 지향 프로그래밍에서 클래스의 모든 인스턴스에서 공유되는 클래스 변수로 사용된다.
지역 변수
프로그래밍
종류변수
스코프지역 스코프
사용 가능 범위특정 서브루틴 또는 블록 내부
접근선언된 서브루틴이나 블록 내에서만 접근 가능
생명 주기서브루틴이나 블록 실행 동안만 존재
소멸서브루틴이나 블록 실행 종료 시 소멸
C/C++
선언 위치함수 내부 또는 블록 내부
스토리지 클래스자동 변수 (auto) 또는 정적 변수 (static)
초기화선언 시 초기화되지 않으면 쓰레기값을 가짐
가시성선언된 블록 내부에서만 보임
Java
선언 위치메서드 내부 또는 블록 내부
초기화컴파일러에 의해 기본값으로 초기화됨 (예: int는 0, boolean은 false)
가비지 컬렉션더 이상 참조되지 않으면 가비지 컬렉터에 의해 회수됨
Python
선언 위치함수 내부
스코프 규칙LEGB 규칙 (Local, Enclosing, Global, Built-in)에 따름
생명 주기함수 호출 동안만 존재
삭제del 키워드를 사용하여 명시적으로 삭제 가능
JavaScript
선언 키워드var, let, const
스코프함수 스코프 (var) 또는 블록 스코프 (let, const)
호이스팅var로 선언된 변수는 호이스팅됨 (선언 전 사용 가능, 값은 undefined)
클로저외부 함수의 변수에 접근 가능한 클로저 생성 가능

2. 스코프 (Scope)

지역 변수는 어휘적(정적) 스코프 또는 동적 스코프를 가질 수 있지만, 대부분의 경우 어휘적 스코프가 사용된다.

은 동적 지역 변수와 사전적(lexically-scoped) 지역 변수를 모두 지원한다. `local` 키워드를 사용하면 동적 지역 변수를, `my`를 사용하면 사전적 지역 변수를 정의할 수 있다. 그러나 동적 변수 지정은 오늘날 흔히 쓰이지 않으므로 펄 문서에서는 "`local`은 대부분의 사람들이 'local'로 생각하는 것이 아니다"라고 경고한다.[10] `local` 키워드는 전역 변수에 일시적인 동적 값을 부여하며, 이는 해당 블록이 끝날 때까지 유지된다. 이 변수는 블록 내에서 호출되는 모든 함수에서 볼 수 있다.[11]

다음은 펄 코드 예시와 그 출력 결과이다.



$a = 1;

sub f() {

local $a;

$a = 2;

g();

}

sub g() {

print "$a\n";

}

g();

f();

g();



```text

1

2

1

```

C 언어와 C++ 표준 규격 문서에서는 "지역 변수"라는 용어를 직접 사용하지 않지만, 함수 내에서 같은 블록 내에서만 참조 가능한 변수를 편의상 지역 변수라고 부른다.

함수 f에서 지역 변수 a의 스코프(가시성)는 함수 f 내에서, 변수 a가 선언된 위치부터 변수 a가 정의된 블록을 벗어날 때까지이다. 스코프 밖에서는 참조할 수 없다. 지역 변수 a를 정의한 블록 내에서 다른 함수 g를 호출하면, 함수 g에서는 변수 a가 보이지 않지만 메모리 상에는 여전히 존재한다. 함수 g가 종료되고 함수 f로 돌아와 변수 a의 스코프에 들어가면 다시 보이게 된다. 다른 함수(다른 블록)에서 같은 이름의 지역 변수를 정의해도 서로 영향을 주지 않으므로 이름 충돌을 걱정할 필요가 없다.

Java에서 변수는 인스턴스 변수, 클래스 변수, 지역 변수, 가인수의 네 가지 종류로 나뉜다.[8] 배열의 요소는 "인스턴스 변수"로, 메서드, 생성자, catch 절의 인수는 "가인수"로 분류된다. Java에서는 메서드 내에서 선언된 변수를 지역 변수라고 부른다.

2. 1. 어휘적 스코프 (Lexical Scope)

대부분의 언어에서 지역 변수는 어휘적 스코프를 가지며, 이는 변수의 유효 범위가 소스 코드 상에서 변수가 선언된 블록 내로 한정됨을 의미한다. 해당 블록 내에서 변수는 존재하고 그 값에 바인딩되지만, 블록 외부에서는 변수에 접근할 수 없다.[7] C, C++, Java, Ruby 등에서 이러한 어휘적 스코프가 사용된다.

C 언어의 경우, 함수 내에서 선언된 변수를 지역 변수라고 부르며, 이 변수는 해당 함수 내에서만 접근 가능하다. C99 이전에는 블록 시작 부분에서만 변수를 정의할 수 있었지만, C99부터는 C++처럼 임의의 위치에서 정의할 수 있게 되었다.

예시 코드:

```c

#include

void g(void); /* 함수 g 의 전방 선언 */

void f(void) {

/* 함수 f 의 지역 변수 */

int a, b;

a = 1;

b = 2;

g(); /* 함수 g 의 호출 */

/* 함수 f 의 지역 변수는, 다른 함수 내의 지역 변수와는 별개이며, 영향을 받지 않는다 */

printf("%d, %d\n", a, b);

}

void g(void) {

/* 함수 g 의 지역 변수 */

int b;

/* 아래는 컴파일 에러가 발생한다 */

/*a = -1;*/

/* 다른 함수 내의 동일한 이름의 지역 변수에는 영향을 주지 않는다 */

b = -2;

}

```

위 코드에서 함수 `f` 내의 지역 변수 `a`와 `b`는 함수 `g`에서는 보이지 않지만, 메모리 상에는 여전히 존재한다. 함수 `g`가 종료되고 `f`로 돌아오면 다시 보이게 된다. 다른 함수에서 같은 이름의 지역 변수를 정의해도 서로 영향을 주지 않는다.

동일한 함수 내에서도 블록에 따라 지역 변수의 스코프가 달라진다.

```c

void Function(void) {

int i = 1; /* 스코프가 넓은 지역 변수 */

{

int j = 1; /* 스코프가 좁은 지역 변수 */

}

}

```

C 언어에서 지역 변수의 수명은 기본적으로 해당 변수를 정의한 블록을 벗어날 때까지이다. `static` 키워드를 사용하면 정적 지역 변수가 되어 프로그램의 생존 기간과 동일하게 된다.

Java에서도 메서드 내에서 선언된 변수를 지역 변수라고 부르며, C/C++와 유사한 스코프 개념을 가진다. 그러나 C/C++와 달리 정적 지역 변수를 정의할 수 없다. 초기화되지 않은 지역 변수에 접근하는 코드는 C/C++에서는 정의되지 않은 동작을 유발하지만 컴파일은 통과하는 반면, Java에서는 컴파일 오류가 발생한다.

2. 2. 동적 스코프 (Dynamic Scope)

은 동적 지역 변수와 사전적(lexically-scoped) 지역 변수를 모두 지원한다. `local` 키워드를 사용하면 동적 지역 변수를, `my`를 사용하면 사전적 지역 변수를 정의할 수 있다. 동적 변수 지정은 오늘날 흔히 쓰이는 것이 아니므로 펄 문서는 "`local`은 대부분의 사람들이 'local'로 생각하는 것이 아니다"라고 경고한다.[10] `local` 키워드는 전역(package) 변수에 일시적인 동적 값을 제공하며, 이는 감싸고 있는 블록이 끝날 때까지 지속된다. 이 변수는 블록 내에서 호출된 모든 함수에서 볼 수 있다.[11]

동적 스코핑(또는 동적 스코프)에서 변수 이름의 유효 범위가 특정 블록이면, 그 범위는 해당 블록과 그 블록에서 (다른 선언으로 재정의되지 않는 한) 전이적으로 호출되는 모든 함수를 포함한다. 블록이 종료되면 변수 이름은 더 이상 존재하지 않는다. Perl과 Common Lisp처럼 프로그래머가 변수를 정의하거나 재정의할 때 정적 또는 동적 스코핑을 선택할 수 있게 하는 언어도 있다. 동적 스코핑을 사용하는 언어로는 Logo, Emacs Lisp, 셸 언어인 bash, dash, MirBSD Korn 셸(mksh)의 "local" 선언 등이 있다.

3. 정적 지역 변수 (Static Local Variables)

C/C++, Visual Basic, VB.NET 및 PHP와 같은 여러 주류 프로그래밍 언어에서는 ''정적 지역 변수''라는 특별한 유형의 지역 변수를 지원한다. 정적 지역 변수는 함수 호출 간에도 값을 유지하며, 프로그램 실행 동안 단 한 번만 초기화된다. 이는 지역 범위(local scope)를 가지면서 정적 변수와 유사하게 프로그램의 수명 동안 메모리에 그 값이 남아있게 된다.[1]

정적 지역 변수는 일반적인 지역 변수와 달리 함수가 종료되어도 값이 사라지지 않고 유지된다. 일반적인 지역 변수는 함수 내에서 선언된 위치부터 해당 변수가 정의된 블록을 벗어날 때까지만 접근 가능하고, 블록을 벗어나면 자동으로 메모리 할당이 해제된다.[7] 반면, 정적 지역 변수는 프로그램이 시작될 때 한 번 초기화되고, 프로그램이 종료될 때까지 메모리에 남아있다.

C/C++에서는 `static` 키워드를 사용하여 정적 지역 변수를 선언한다. C 언어의 예시는 다음과 같다.



#include

int Function1(void) {

int a = 0; // 일반적인 지역 변수. 함수 호출 시마다 초기화됨.

a += 1;

return a;

}

int Function2(void) {

static int s = 0; // 정적 지역 변수. 프로그램 시작 시 한 번만 초기화됨.

s += 1;

return s;

}

int main(void) {

for (int i = 0; i < 5; ++i) {

printf("auto(%d) = %d\n", i, Function1()); // 매번 1 출력

printf("static(%d) = %d\n", i, Function2()); // 1, 2, 3, 4, 5 출력

}

return 0;

}



위 코드에서 `Function2`의 `s`는 정적 지역 변수이므로, `Function2`가 여러 번 호출되어도 `s`의 값은 계속 유지된다.

C++에서는 정적 지역 변수가 싱글톤 패턴 구현에 사용될 수 있으며, 변수의 수명이 다할 때 소멸자가 호출되는 특징을 이용한 RAII 디자인 패턴에도 활용된다.

4. 언어별 지역 변수

은 동적 범위와 렉시컬 범위(lexical scope) 지역 변수를 모두 지원한다. `local` 키워드는 동적으로 범위가 지정된 지역 변수를 정의하는 데 사용되고, `my`는 렉시컬 범위 지역 변수에 사용된다. 오늘날 동적 범위는 덜 일반적이므로 Perl 문서는 "`local`은 대부분의 사람들이 '지역'이라고 생각하는 것이 아니다."라고 경고한다.[2] `local` 키워드는 전역(패키지) 변수에 임시의 동적 범위 값을 부여하며, 이는 묶음의 끝까지 지속된다. 그러나 변수는 묶음 내에서 호출되는 모든 함수에 표시된다.[3] 렉시컬 범위 지역 변수를 만들려면 `my` 연산자를 사용한다.[4]

다음 코드를 통해 작동 방식을 이해할 수 있다.



$a = 1;

sub f() {

local $a;

$a = 2;

g();

}

sub g() {

print "$a\n";

}

g();

f();

g();



위 코드는 다음과 같이 출력된다.

1

2

1

이는 전역 변수 `$a`가 `f()` 내부에서 새로운 ''임시''(지역) 값으로 수정되지만, `f()`의 범위를 벗어나면 전역 값이 복원되기 때문이다. 만약 `local` 대신 `my`를 사용하면 1을 세 번 인쇄했을 것이다. `my`를 사용하면 `$a` 변수는 함수 `f()`의 정적 범위로 제한되고 `g()`에서 보이지 않기 때문이다. Randal L. Schwartz와 Tom Phoenix는 `local` 연산자가 `save`와 같은 다른 이름을 가져야 한다고 주장한다.[5]

루비는 펄의 영향을 받았지만, 지역 변수 표기법이 더 단순하다. 전역 변수 이름은 `$variable_name`과 같이 `$` 기호로 시작해야 하는 반면, 지역 변수는 `variable_name`과 같이 이름 앞에 `$` 기호가 없다(펄에서는 모든 스칼라 값 앞에 `$` 기호가 붙는다). 루비는 기본적으로 정적으로 범위가 지정된 지역 변수만 지원하며, 동적으로 범위가 지정된 지역 변수를 제공하는 라이브러리가 존재한다.[6]

4. 1. C/C++

C/C++에서 지역 변수는 함수 내의 블록 내에서 선언된 변수를 말한다. C99 이전에는 블록 시작 부분에서만 변수를 선언할 수 있었지만, C99부터는 블록 내 임의의 위치에서 선언할 수 있다.[1] 지역 변수의 범위는 선언된 위치부터 블록 끝까지이다.

```c

#include

void g(void); /* 함수 g 의 전방 선언 */

void f(void) {

/* 함수 f 의 지역 변수 */

int a, b;

a = 1;

b = 2;

g(); /* 함수 g 의 호출 */

/* 함수 f 의 지역 변수는, 다른 함수 내의 지역 변수와는 별개이며, 영향을 받지 않는다 */

printf("%d, %d\n", a, b);

}

void g(void) {

/* 함수 g 의 지역 변수 */

int b;

/* 아래는 컴파일 에러가 발생한다 */

/*a = -1;*/

/* 다른 함수 내의 동일한 이름의 지역 변수에는 영향을 주지 않는다 */

b = -2;

}

```

위 코드에서 함수 `f` 내에 선언된 `a`와 `b`는 지역 변수이다. 이 변수들은 `f` 함수 내에서만 접근 가능하다. `g` 함수 내에 선언된 `b`는 `f` 함수의 `b`와는 다른 별개의 변수이다.

동일한 함수 내에서도, 속한 블록에 따라 지역 변수의 스코프(및 수명)가 다르다.

```c

void Function(void) {

int i = 1; /* 스코프가 넓은 지역 변수 */

{

int j = 1; /* 스코프가 좁은 지역 변수 */

}

}

```

위 코드에서 `i`는 `Function` 함수 전체에서 접근 가능하지만, `j`는 안쪽 블록 내에서만 접근 가능하다.

`static` 키워드를 사용하여 정적 지역 변수를 선언할 수 있다. 정적 지역 변수는 프로그램 시작 시 한 번만 초기화되며, 프로그램 종료 시까지 유지된다.[1]

```c

#include

int Function1(void) {

int a = 0; // (1) 일반적인 지역 변수(자동 변수)의 선언과 정의. 초기화는 함수를 호출할 때마다 매번 수행된다.

a += 1;

return a;

}

int Function2(void) {

static int s = 0; // (2) 정적 지역 변수의 선언과 정의. 초기화는 한 번만 수행된다.

s += 1;

return s;

}

int main(void) {

for (int i = 0; i < 5; ++i) {

printf("auto(%d) = %d\n", i, Function1());

printf("static(%d) = %d\n", i, Function2());

}

return 0;

}

```

위 코드에서 `Function1`의 `a`는 함수가 호출될 때마다 초기화되는 반면, `Function2`의 `s`는 프로그램 시작 시 한 번만 초기화되고 그 값을 유지한다.

C++에서는 RAII 디자인 패턴에서 소멸자를 활용하기 위해 지역 변수를 사용한다.

4. 2. Java

Java에서는 메서드 내에서 선언된 변수를 지역 변수라고 부른다. 범위 및 블록 구문은 C/C++와 유사하지만, C/C++와 달리 정적 지역 변수는 정의할 수 없다. 필드(인스턴스 변수와 클래스 변수)는 컴파일러가 타입에 따라 적절한 기본값을 할당하지만, 지역 변수는 기본값이 할당되지 않는다.[9]

다음은 코드 예제이다.

```java

class Foo {

void bar() {

int i = 1; // 범위가 넓은 지역 변수

{

int j = 1; // 범위가 좁은 지역 변수

}

}

}

```

3행에서 선언된 지역 변수 `i`의 범위는 3행부터 7행의 중괄호까지이며, 5행에서 선언된 지역 변수 `j`의 범위는 5행부터 6행의 중괄호까지이다.

초기화되지 않은 지역 변수에 접근하는 코드는 C/C++에서는 정의되지 않은 동작을 일으키지만 컴파일은 통과되는 반면, Java에서는 컴파일 오류가 발생한다.

```java

int x;

if (x == 0) {

}

```

Java의 메모리 해제는 가비지 컬렉션에 의해 수행된다. Java의 지역 변수는 스택 영역에 확보되지만, 클래스나 배열 등의 참조형의 경우 객체 본체는 힙 영역에 생성된다. 지역 변수의 수명이 다하여 그 변수가 가리키고 있던 객체가 전혀 참조되지 않게 되더라도, 그 객체의 메모리 영역이 즉시 해제되는 것은 아니다.

```java

{

int[] a = new int[100];

}

// 블록을 벗어나면 변수 a는 삭제되지만, a가 가리키고 있던 배열 객체 본체의 삭제는 가비지 컬렉터가 담당한다.

4. 3. Perl

은 동적 지역 변수와 사전적(lexically-scoped) 지역 변수를 모두 지원한다. `local` 키워드를 사용하면 동적 지역 변수를, `my` 키워드를 사용하면 사전적 지역 변수를 정의할 수 있다. 오늘날 동적 변수 지정은 흔히 쓰이지 않으므로 펄 문서는 "`local`은 대부분의 사람들이 'local'로 생각하는 것이 아니다"라고 경고한다.[10] `local` 키워드는 전역(package) 변수에 일시적인 동적 값을 부여하며, 이는 감싸고 있는 블록이 끝날 때까지 지속된다. 그러나 해당 변수는 블록 내에서 호출된 모든 함수에서 볼 수 있다.[11] 사전적 지역 변수를 만들려면 `my` 연산자를 대신 사용한다.[12]

동작 방식을 이해하기 위해 다음 코드를 보자:

```perl

$a = 1;

sub f() {

local $a;

$a = 2;

g();

}

sub g() {

print "$a\n";

}

g();

f();

g();

```

위 코드의 출력은 다음과 같다:

```text

1

2

1

```

이는 전역 변수 `$a`가 `f()` 함수 내부에서 새로운 ''임시''(지역) 값으로 수정되지만, `f()` 함수의 범위를 벗어나면 전역 값이 복원되기 때문이다.

`local` 대신 `my`를 사용하면 1이 세 번 출력된다. `my`를 사용하면 `$a` 변수는 `f()` 함수의 정적 범위로 제한되어 `g()` 함수에서는 보이지 않기 때문이다. Randal L. Schwartz와 Tom Phoenix는 `local` 연산자가 `save`와 같은 다른 이름을 가져야 한다고 주장한다.[5]

4. 4. Ruby

루비는 펄의 영향을 받았지만, 지역 변수 표기법이 더 단순하다. 전역 변수는 `$` 기호로 시작하는 반면(예: `$variable_name`), 지역 변수는 `$` 기호 없이 이름만으로 선언된다(예: `variable_name`). 펄에서는 모든 스칼라 값 앞에 `$` 기호가 붙는다. 루비는 기본적으로 정적으로 범위가 지정된 지역 변수만 지원하며, 동적으로 범위가 지정된 지역 변수를 제공하는 라이브러리가 존재한다.[6]

참조

[1] 웹사이트 Current C standard http://www.open-std.[...]
[2] 웹사이트 perldoc.perl.org: local http://perldoc.perl.[...]
[3] 웹사이트 perldoc.perl.org: perlsub: Temporary Values via local() http://perldoc.perl.[...]
[4] 웹사이트 perldoc.perl.org: perlsub: Private Variables via my() http://perldoc.perl.[...]
[5] 서적 Learning Perl 3rd edition https://archive.org/[...] O'REILLY 2001-07-01
[6] 간행물 LSpace: Dynamic scope for Ruby http://cirw.in/blog/[...] 2013-10-16
[7] 문서 ISO/IEC 9899:1999, §6.2.4 Storage durations of objects
[8] 웹사이트 Variables (The Java™ Tutorials > Learning the Java Language > Language Basics) https://docs.oracle.[...]
[9] 웹사이트 Summary of Variables (The Java™ Tutorials > Learning the Java Language > Language Basics) https://docs.oracle.[...]
[10] 웹사이트 perldoc.perl.org: local http://perldoc.perl.[...]
[11] 웹사이트 perldoc.perl.org: perlsub: Temporary Values via local() http://perldoc.perl.[...]
[12] 웹사이트 perldoc.perl.org: perlsub: Private Variables via my() http://perldoc.perl.[...]



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com