어떤 함수가 실행되면 기본 작업공간과 별도로 그 함수만의 작업공간이 생성되어 함수 내부에서 사용되거나 생성된 객체가 저장되게 된다. 그리고 함수의 실행이 끝나면 그 작업공간은 소멸되므로 함수 내에서 초기화된 변수는 함수의 실행 끝나는 시점에서 소멸된다. 함수 내부에서 사용할 수 있는 외부 변수는 다음과 같은 세 가지 경로로 전달된다.
❶ 입력 변수
❷ global로 선언된 변수
❸ 함수 내부에서 초기화되지 않고 호출된 곳의 workspace에서 정의된 변수
여기서 ❶과 ❷는 MATLAB에서도 동일하지만 ❸의 경우는 그렇지 않다. 함수가 호출되면 호출된 곳의 작업공간과는 별도로 그 함수만의 분리된 작업공간이 생성된다. 편의상 호출된 곳의 작업공간을 기본 작업공간(base workspace, BWS)라고 칭하겠다. 만약 함수 내부에서 어떤 변수를 참조하려고 하면 먼저 자신의 작업공간을 먼저 검색해보고 만약 없다면 기본 작업공간에서 찾아본다. 두 곳 모두에서 없다면 에러가 발생될 것이다.
예를 들어서 다음과 같은 함수가 정의되었다고 가정하자.
function y=fA(x)w=(w+1)^2 // (a)y=x*w // (b)endfunction |
이렇게 정의한 후
>> fA(1) |
이라고 호출하면 에러가 발생된다. 왜냐면 (a)의 우변에서 쓰이는 변수 w는 현재의 workspace에서도 없고 기본 작업 공간에서도 초기화되지 않았기 때문이다.
[그림 1] 작업 공간의 개념도
하지만
>> w=1>> fA(1) |
와 같이 변수 w를 먼저 초기화한다면 이제는 4라는 결과값이 표시될 것이다. 한 가지 정말로 혼동하기 쉬운 것은 (a)의 우변의 변수 w는 기본 작업 공간에서 참조하고 좌변의 w는 이 함수 자신의 작업 공간에 새로운 변수로 초기화된다는 것이다. 따라서 (b)의 변수 w는 이렇게 새롭게 생성된 변수가 참조된다. 기본 작업 공간의 변수 w가 아님에 주의해야 한다. 이 변수 w와 기본 작업 공간의 변수 w는 별개의 것이므로 기본 작업 공간에서는 여전히 1값을 유지한다. 이렇게 기본 작업 공간에서 이미 초기화되어 있는 변수를 함수 내부에서 다시 초기화한 경우 “shadowed” 되었다고 하며 이 경우 기본 작업 공간의 변수를 접근할 수는 없게 된다.
[그림 2] 함수의 작업공간과 기본 작업공간은 분리되어 있다.
만약 기본 작업 공간에서 변수 w를 global로 지정한 후 초기화했다면 어떤 일이 발생할까.
>> global w, w=1>> fA(1)>> disp(w) |
이 경우에도 변수 w는 여전히 1값을 유지하며 global로 지정했더라도 함수 내부에서 그 값을 변경할 수는 없다. 즉, 앞의 경우와 동일하게 동작한다는 것이다. 그렇다면 함수 내부에서 여전히 기본 작업공간의 변수를 접근할 수 있는데 global로 지정해주어야 하는 필요가 있을까하는 의문이 생긴다. 일견 아무런 차이점이 없어 보이기 때문이다. 함수 내부에서 상위 workspace의 변수값을 변경해주려면 함수의 내부에서도 global로 지정해 주어야 한다.
function y=fB(x)global ww=(w+1)^2y=x*wendfunction |
이제
>> fB(1)>> disp(w) |
를 실행하면 변수 w는 4로 바뀐다. 즉, 상위 workspace의 변수 w가 fB()함수 내부에서 바뀐 것이다. 이와 같이 외부 변수의 값을 바꿀 필요가 있다면 외부에서뿐만 아니라 내부에서도 그 변수를 global로 지정해 주어야 한다.
[그림 3] 글로벌 변수의 동작 개념도
함수의 결과값을 기본 작업 공간으로 내보내는 데에도 다음과 같은 세 가지 방법이 있다.
❶ 출력 변수로 반환하는 방법
❷ global로 지정된 변수를 이용하는 방법
❸ resume 혹은 return 명령의 인수를 이용하는 방법
❶ 은 함수의 정의부에서 선언한 출력변수를 통해서 기본 작업 공간으로 값을 내보내는 것이고 ❷는 직전 절에서 기술한 바와 같이 함수의 내부에서 global로 지정한 변수를 통해서 기초 작업 공간에서 접근할 수 있는 전역 공간에 변수값을 내보내는 방법이다.
함수 내부에서 return 이나 resume을 만나면 그 즉시 함수가 종료되는데 보통은 단문으로 사용되어서 함수를 강제로 종료시키는 기능을 수행한다. 하지만 다음과 같은 문법도 가능하다.
[x1, x2, … xn] = return(a1, a2, … an)[x1, x2, … xn] = resume(a1, a2, … an) |
이러한 명령들은 함수 내부의 변수들 a1, a2, … , an 을 호출한 곳의 작업 공간에 변수 x1, x2, …, xn 으로 내보내는 기능을 수행한다. 예를 들면 다음과 같다.
function foo(a)a=a+1b=resume(a) //(*)c=52 // (**)endfunction |
이 예제에서 (**)줄은 실행되지 않고 (*)줄에서 함수는 종료된다. 또한 기본 작업공간에 변수 b를 생성시켜서 함수 내부의 a변수 값을 넘겨주게 된다. 따라서
>> foo(42) |
라고 함수를 실행시키면 workspace에 변수 b가 43값으로 생성된다.
그렇지만 Scilab 매뉴얼(도움말)에 의하면 이러한 용법은 쓸데없이 프로그램의 복잡도만 증가시키므로 출력 변수를 이용하는 것이 바람직하다고 기술되어 있다. 따라서 가급적 ❶번 방법을 주로 사용하고 필요시 ❷번 방밥을 사용하도록 하는 것이 좋다. 또한, resume명령은 pause명령에 의해서 실행이 멈춘 함수를 다시 시작시키는 데에도 사용되는 명령이다.
댓글 없음:
댓글 쓰기