변수

변수의 특성

  • 이름

    변수를 참조하기 위해 사용하는 문자들

  • 주소

    변수의 첫 번째 메모리 셀

  • 수명(life time, extent)

    변수가 값을 저장할 기억 장소를 할당 받은 때부터 그 기억 장소가 더 이상 그 변수 값을 보유하지 않을 때까지를 말한다.

  • 타입

    변수에 할당될 수 있는 값을 결정한다.

선언(declaration)은 변수 이름을 기억 장소의 주소, 속성, 매개 변수와 결합 시킨다.

별명(aliasing)은 둘 이상의 이름이 동일 주소를 참조하는 경우를 말한다. 문장의 실행 이후에 변수의 값이 바뀌는 부작용이 있다.

바인딩 시간

이름에 속성을 관련시키는 일련의 작업을 바인딩이라고 한다. 바인딩 시간은 바인딩, 결합이 일어나는 시간을 의미한다.

바인딩 시간의 구분

  • 실행 시간 : 변수에 값을 바인딩 하거나, 변수에 기억 장소를 바인딩 한다.

    • 예를 들면 형식 매개변수와 실 매개변수에 대한 기억 장소의 바인딩은 서브프로그램의 시작에서만 이루어 진다.
    • 배정문을 이용한 변수에 대한 값의 바인딩은 실행중 임의의 시점에서 바인딩이 이루어 진다.
  • 컴파일 시간 : 세가지 바인딩이 있다.

    • 프로그래머에 의한 변수의 타입, 문장 구조등에 대한 결정이다.
    • 프로그래머와 상관없이 컴파일러에 의한 바인딩. 배열이 어떻게 저장되고, 배열에 대한 명세표가 어떻게 만들어지는가는 컴파일러가 결정 한다.
    • 프로그램을 실행할 컴퓨터의 실제 주소가 로더에 의해 바인딩 된다.
  • 언어 구현 시간

    프로그래밍 언어가 다르더라도 그 연산 Instruction은 하드웨어에 따라 다르다.

  • 언어 설계(정의) 시간

    데이터 구조, 프로그램 구조 등의 특성들은 언어를 정의 할 때 결정 된다.

정적 바인딩과 동적 바인딩

  • 정적 바인딩
    • 프로그램이 실행 되기 이전에 일어난다.
    • 융통성이 없고 실행의 효율이 뛰어나다.
    • 컴파일러 바인딩
  • 동적 바인딩
    • 실행 시간 중에 일어난다.
    • 융통성이 있고 실행이 효율적이다.
    • 신뢰성이 떨어진다.
    • 구현 비용이 크다.
    • 인터프리터 바인딩

      명시적 선언과 묵시적 선언

    • 명시적 선언(Explicit declaration) 선언문을 사용하여 변수 이름들을 열거하여 특정 타입과 연관 시키는 방법
    • 묵시적 선언(implicit declaration) 선언문을 사용하지 않고 디폴트 규칙을 통해서 변수에 타입을 연관시키는 방법

영역

선언문과 영역

영역 혹은 유효범위란 변수의 이름이 모두 동일하게 사용되는 프로그램의 부분을 말한다. 만일 변수가 문장에서 참조 가능하면 가시적이라고 하고, 영역에서 벗어나거나 동일한 이름을 갖는 다른 변수에 의해 가려지면 비가시적이라고 한다. 초기 Fortran은 서브루틴 내에서 선언된 모든 변수의 영역이 그 서브루틴 내부인 지역 영역 규칙(local scope rule)을 사용했다. 다음은 FORTRAN의 예다

C   주 프로그램
    COMMON /A/X,Y,z(10)
    COMMON GO,IRED,TEMP
    .
    .
    END
    SUBROUTINE A1(P,Q)
    COMMON GO, IRED, TEMP
C   주 프로그램과 공유되는 COMMON문
    INTEGER ISUM,ITOTAL
C   여기에서 선언된 변수들은 서브루틴 A1의 지역 변수
    .
    END
    SUBROUTINE A2(P,Q)
    COMMON /A/X,Y,Z(10)
C   주 프로그램과 공유되는 레이블이 붙은 COMMON문

COMMON의 사용으로 변수는 공유될 수있다. 서브루틴의 이름은 전역으로 취급된다. COMMON선언 내에 정의된 것을 제외한 모든 변수는 지역 변수이다.

블록 구조와 영역

선언은 블록 구조와 관련이 있다. 블록은 일련의 문장집합으로 자체적인 선언을 가질 수 있는 프로그램의 부분을 말한다. 블록 내의 선언을 지역적(local) 이라 하고, 밖을 비지역적(nonlocal) 이라고 한다. C에서는 어느 블록에도 속하지 않고 프로그램의 모든 함수를 포함하는 영역인 외부영역(external scope)를 가진다 이 외부영역이 전역 영역의 역할을 수행한다.

블록 내에서 선언되지 않은 변수를 자유 변수(비지역 변수)라고 한다. 자유 변수를 처리하는 해결책은 세가지가 있다.

  • 자유변수를 불법적인 것으로 간주 한다.
  • 영역 규칙이 블록구조를 따르는 어휘 영역을 갖는다.(lexical enclosing scope)
  • 자유 변수가 동적으로 포함되는 영역 내에서 정의된다.(dynamically enclosing scope)

정적 영역 규칙

자유 변수의 적절한 타입을 결정하기 위해 변수의 이름이 선언된 것을 발결할 때까지 자신의 프로그램 단위를 포함하는 조상 프로그램을 조사 한다.

정적 영역 규칙이 변수의 정확한 정의를 결정하는데 이용된다고 하더라도 영역 구멍 문제(hole-in-scope) 를 야기한다. 이를 해결하기 위해 c++에서는 영역 해결 연산자(scope resolution operator) 를 이용한다.

동적 영역 규칙

변수의 적절한 저의가 실행시간에 결정되도록 하는 규칙이다. 오류를 발생시킬 가능성이 높은 것으로 판명되어 현대의 대부분의 언어에서는 사용되지 않는다.

영역 규칙 비교

  PROGRAM L;
      var n: char;
      procedure W;
      begin
          writeln(n)
      end;
      procedure D;
          var n: char;
      begin
          n := 'D';
          W
      end;
    begin {L}
      n := 'L';
      W;
      D
    end
  • 정정 규칙일때 출력
    L
    L
    
  • 동적 규칙일때 출력
    L
    D
    
int x = 0;
int f() {return x;}
int g() {int x = 1; return f()}
  • g() 실행시 정적 규칙일 때 return x
    0
    
  • 동적 규칙일때
    1
    

perl에서 정적 규칙은 예약어 my를 사용하고 동적 규칙은 local을 사용한다.

$x = 0;
sub f{return $x;}
sub g{my $x = 1; return f();}
print g(). "\n";

->
return $x 는 0

$x = 0;
sub f{return $x;}
sub g{local $x = 1; return f();}
print g(). "\n";
-> return $x 는 1

정적 영역 규칙을 사용하는 언어로 작성된 프로그램이 읽기가 더 쉽고, 신뢰성이 더 높고, 더 빠르게 실행된다.

기억 장소 할당

정적 할당

정적 변수 는 프로그램의 실행이 시작되기 전에 기억 장소가 바인딩되고 실행이 끝날 때까지 바인딩이 유지된다. 정적 할당이 이루어지는 공간은 정적(전역) 영역이다. 정적 변수는 주소를 부여하는데 효율적이다. 재귀를 허용하지 않는다.

동적 할당

동적 변수 는 변수의 타입은 컴파일 시간에 알려지지만 기억 장소가 실행 시간에 선언에 도달할 때 할당된다. 힙 변수와 구분하기 위해 스택 동적 변수 라고한다. malloc이 아니다 c에서는 모든 일반 변수에 (auto)가 생략 되있는데 이것이 동적할당을 의미한다. 재귀를 허용한다.