티스토리 뷰

우선, parameter에는 formal parameter와 actual parameter가 있다.

예제 코드를 통해 formal parameter와 actual parameter를 비교해보자.

class Solution {
	public static void main(String[] args) throws Exception {
    	int a = 1;
        int b = 2;
    	System.out.println(getSum(a,b));
    }
    
    public static int getSum(int x, int y) {
    	return (x+y);
    }
}

- Formal parameter : 함수(subprogram)를 정의할 때와 함수 안에서 사용되는 parameter (x, y)

- Actual parameter : 함수(subprogram)를 호출할 때 사용하는 실제로 쓰는 값을 가진 parameter (a, b)

위 코드 예제에서는 getSum이라는 함수를 정의할 때 사용한 integer x와 y가 formal parameter이고, getSum이라는 함수를 호출할 때 사용되며, 실제 함수가 동작하는데 쓰이는 integer a와 b가 actual parameter가 된다.

 

함수를 사용할 때 Actual parameter와 해당하는 formal parameter를 bind (correspondence)해주는 방법에도 두 가지가 있다.

 

1. Positional parameter : 우리가 흔히 쓰는 방법으로, formal parameter의 순서에 맞게 actual parameter를 전달해주는 방법이 다. 위 예제 코드에서 int x에 int a가 할당되고, int y에 int b가 할당되는 것은 parameter의 순서에 따른 할당이므로 positional parameter 방식을 사용한 것이다.

2. Keyword parameter : 이름에서 유추할 수 있듯이, formal parameter에 actual parameter의 순서와 상관없이 keyword를 사용하여 할당해줄 수 있다. 파이썬에서 지원되는데, 예제 코드는 다음과 같다.

def getSub(a, b) :
	return (a-b)

a와 b를 뺀 값을 리턴해주는 간단한 함수 getSub가 있을 때, 다음 3가지 case의 실행 결과를 생각해보자.

getSub(1,2)
getSub(2,1)
getSub(b=2,a=1)
getSub(b=1,a=2)

1. getSub(1,2) : 1-2인 -1이 리턴된다.

2. getSub(2,1) : 2-1인 1이 리턴된다.

3. getSub(b=2,a=1) : 1번과 같은 케이스로 -1이 리턴된다.

4. getSub(b=1,a=2) : 2번과 같은 케이스로 1이 리턴된다.

즉, formal parameter의 이름에 순서 상관없이 actual parameter를 지정해 줄 수 있다.

 

본격적으로, formal parameter와 actual parameter 사이의 data passing이 어떻게 이루어지는지 알아보자.

 

의미적으로 formal parameter와 actual parameter사이의 passing을 다음과 같이 구별할 수 있다.

 

- In mode : formal parameter가 actual parameter로부터 data를 받는 것

- Out mode : formal parameter가 actual parameter에 data를 보내는 것

- Inout mode : formal parameter가 actual parameter의 data를 받기도 하고, 보내기도 하는 것

Semantic한 의미의 parameter passing (in, out, inout mode)

 

그리고, data transfer model에도 두 가지 방법이 있다.

- 실제 값을 복사하는 경우

- 값을 참조할 주소 (access path)를 전달하는 경우

Data transfer의 두 가지 모델

이제, parameter passing의 여러 가지 방법에 대해 알아보겠다.

 

1. Pass by Value (In Mode) : actual parameter의 value가 복사되어 formal parameter를 initialize 하고 local variable처럼 사용된다.

- 장점 : scalar 변수에 대해서 빠르다

- 단점 : copy로 인한 추가적인 저장공간(storage)이 필요 (만약 array 같이 큰 parameter면 매우 비효율적)

 

2. Pass by Result (Out Mode) : actual parameter의 값을 가져오지 않기 때문에 어떤 값도 subprogram(함수)에 전달되지 않는다. 대신, formal parameter가 local variable의 역할을 한다. 그러나, subprogram의 결과가 actual parameter에 전달된다.

- 단점 : actual parameter의 collision이 발생할 수 있는데, 동일한 변수로 함수를 호출했을 때 return 순서에 의해서 actual parameter에 할당되는 값이 바뀔 수 있다.

(ex) set(a, a)를 실행하고 set(int x, int y)라는 함수는 x=10, y=20을 진행한다고 할 때 a에 10이 할당되는지 20이 할당되는지 alias 현상이 일어나는 것을 말함. (compiler에 따라 결과가 다름)

 

3. Pass by Value-Result (Inout Mode) : Actual parameter의 값이 formal parameter에 복사된다. 그리고 actual parameter에 다시 data를 전달할 수 있다.

 

4. Pass by Reference (Inout Mode) : Actual parameter의 access path (address)를 전달하여, formal parameter에서 actual parameter를 share 하여 사용한다.

- 장점 : 시간과 메모리 측면에서 passing 과정이 효율적 (복사 과정과 여러 공간이 필요하지 않기 때문에)

- 단점 : formal parameter에 접근하는데 걸리는 시간이 pass by value 방식보단 느리다 (indirect addressing이 요구되기 때문에). 그리고, 원치 않는 side effect와 alias가 발생할 가능성이 있다.

 

5. Pass by Name (Inout Mode) : Actual parameter의 이름으로 해당하는 formal parameter가 모두 대체된다. Algol이라는 언어에서 사용되며, 대부분의 언어에서 거의 사용되지 않는다.

 

6. Pass by Assignment (Inout Mode) : 객체의 종류에 따라서 call by reference 또는 call by value가 결정된다.

 

 

마지막으로, 주로 사용되는 언어에 대해 어떤 parameter passing을 사용하는지 알아보겠다.

 

1. C : pass-by-value가 주로 이뤄지고, pointer를 parameter로 사용하면 pass-by-reference가 일어난다.

2. C++ : reference type를 사용하면 pass-by-reference가 일어난다.

3. JAVA : Pass By Value (Reference Type을 인자로 전달할 때, Reference를 넘기지만 그 Reference가 아니라 사본의 값을 넘기기 때문에 Pass By Reference로 볼 수 없음.)

4. Python : pass-by-assignment를 사용 (모든 value가 object)하며 actual parameter가 formal parameter에 assign된다.

 

이 방식을 알아야 내가 원하는 대로 함수를 자유롭게 구현이 가능하다.

추후 이 포스팅이 꼭 도움이 되었으면 좋겠다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함