7-3.통용 범위

7-3-가.통용 범위 규칙

변수나 함수, 태그 같은 명칭은 상호 구분되어야 하므로 중복되어서는 안된다. 그래서 같은 이름을 가진 두 개의 변수를 선언할 수 없다. 다음과 같이 작성하면 에러로 처리된다.

 

void main()

{

     int i;

     double i;

 

i라는 명칭으로 정수형 변수와 실수형 변수를 동시에 선언했다. 이유를 설명할 필요도 없이 이 코드는 에러로 처리된다.

 

'i' : redefinition; different basic types

 

i라는 명칭이 정수형으로 선언되었다가 실수형이라는 다른 타입으로 중복 선언되었다는 뜻이다. 이름이 중복되면 다음에 i를 참조할 때 정수형 변수 i를 의미하는 것인지 실수형 변수 i를 의미하는 것인지 구분할 수 없는 모호함이 발생할 것이다. 컴퓨터 프로그램의 논리에 모호함이란 절대 있을 수 없으므로 명칭의 중복은 허락되지 않는다.

명칭이 중복되지 말아야 한다는 것은 지극히 상식적이다. 그러나 이 법칙에 예외가 있는데 통용 범위가 다른 명칭끼리는 같은 이름을 가질 수도 있다. 다음 예를 보자.

 

void func()

{

     int i;

     ....

 

void proc()

{

     double i;

     ....

 

func 함수에서는 i를 정수형으로 선언했고 proc 함수에서는 같은 이름의 i를 실수형으로 선었했지만 논리적으로 아무 문제가 없다. 둘 다 지역변수이고 통용 범위가 분명히 다르기 때문에 같은 명칭 i를 참조하더라도 func 함수에서는 정수형으로, proc 함수에서는 실수형으로 구분할 수 있어 모호함이 발생하지 않는다.

위 코드가 아무런 문제가 없다는 것은 아마 쉽게 이해가 갈 것이다. 이런 경우 외에 특수한 경우는 두 변수의 통용 범위가 겹쳐 있을 때인데 같은 명칭으로 선언된 전역변수와 지역변수의 관계가 이런 경우에 해당된다. 다음 예제를 보자.

 

: Scope

#include <Turboc.h>

 

void func() ;

int i=3;

 

void main()

{

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

     func();

}

 

void func()

{

     int i=5;

 

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

}

 

main에서 i값을 한 번 출력했고 func에서 다시 한 번 i값을 출력했다. 실행 결과는 다음과 같다.

 

i=3

i=5

 

전역변수 i가 3으로 정의되어 있고 func 함수에서 지역변수 i를 같은 이름으로 선언하여 5로 초기화하였다. 전역 i는 모든 함수에서 통용 가능하므로 main 함수에서 당연히 이 변수를 참조할 수 있다. func 함수에서는 전역 i와 지역 i가 동시에 존재하므로 이 함수에서 i를 참조하면 어떤 i를 의미하는지 모호함이 발생하게 된다.

그러나 이 상황은 에러로 처리되지 않는데 컴파일러는 하나의 명칭에 대해 통용 범위가 겹쳐 있을 경우 좁은 범위를 가지는 명칭에게 우선권을 줌으로써 모호한 상황을 극복한다. 규칙을 마련하고 이 규칙대로 동작하면 모호하지 않다. 위 예에서 func 함수 내에서 i 변수를 참조하면 이는 지역변수 i를 의미한다. 전체가 소유하는 전역 i보다는 func 함수에게 소속된 지역 i를 참조하는 것이 논리적으로 합당하다. 그래서 main이 출력하는 i는 전역변수이며 3의 값을 가지고 func가 출력하는 i는 자신의 지역변수이며 5의 값을 가지는 것이다.

C 언어에서는 전역변수와 지역변수의 이름이 중복될 때 지역변수가 선언된 함수에서 전역변수를 참조할 수 없다. 위 예의 func 함수는 전역변수 i를 읽거나 참조할 수 없는데 전역 i가 지역 i에 의해 완전히 가려져 있기 때문이다. 변수가 아직 존재하지만 가려져 있어 쓸 수 없는 상태이며 이 상황을 가시성(Visibility)이 없다고 표현한다. 그러나 C++에서는 가려져 있는 전역변수를 참조할 수 있는 별도의 범위 연산자 ::을 사용하면 전역 i를 읽을 수 있다. func 함수의 끝에 다음 코드를 추가해 보자.

 

printf("global i=%d\n",::i);

 

::i라는 명칭은 전역변수 i라는 뜻이다. :: 연산자에 대해서는 차후에 C++에서 다시 다루게 될 것이다. 통용 범위 규칙은 아주 상식적이기 때문에 비교적 이해하기 쉽다. 요약하자면 "같은 통용 범위내에서는 명칭이 중복될 수 없으며 전역, 지역 명칭이 중복된 경우는 지역이 우선이다"라고 할 수 있다.