[프로그래밍 언어론] 파라미터 전달 방식(pass by value, pass by reference, pass by result, pass by value-result, pass by name) 비교 | call by value와 call by reference

파라미터 전달 방식

프로그래밍을 공부한 사람은 다들 Call by value 혹은 Call by reference 등에 대해 들어본 적이 있을 것이다.

이는 함수 호출 방식을 값에 의한 호출, 참조에 의한 호출로 구분한 것이다. 함수 호출 방식에 따라 파라미터 전달 방식이 달라지는데, 이에 대해 알아보자.

Pass by value (= Call by value)

1. Pass by value는 함수의 파라미터로 변수의 값을 복사해서 전달하는 방식이다.

2. 즉, 원래의 값에 영향을 주지 않고 함수 내로 복사된 값을 전달한다.

3. 값을 복사하기 때문에 변수의 크기가 클수록 비용이 증가하게 된다.

4. 따라서 크기가 큰 변수를 파라미터로 전달할 때 적절한 방법이 아니다.

5. 원래의 값이 변경되면 안 되는 경우에 사용할 수 있다. 

 

예를 들어 아래의 경우를 보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
 
void swap(int num1, int num2)
{
    int temp = num1;
    num1 = num2;
    num2 = temp;
}
void main()
{
    int a = 20, b = 60;
    swap(a, b);
    printf("a: %d, b: %d", a, b);
    // 출력결과 - a: 20, b: 60
}
cs

swap(int num1, int num2) 함수는 파라미터로 들어온 num1과 num2의 값을 설계하기 위한 함수다.

하지만 pass by value 방식을 사용했기 때문에 함수 내에서만 값이 바뀌고 원래 값은 전혀 영향을 받지 않는다. 

따라서 원래 값은 바뀌지 않게 된다.

Pass by reference (= Call by reference)

1. Pass by reference는 함수의 파라미터로 변수의 주소를 전달하는 방식이다.

2. 즉, 변수의 주소를 전달하기 때문에 원래 변수의 값에도 영향을 주게 된다.

3. 값을 복사하지 않고 주소를 전달하기 때문에 변수의 크기에 상관없이 비용이 일정하다.

4. 따라서 크기가 큰 변수를 파라미터로 전달할 때 적절한 방법이다.

 

예를 들어 아래의 경우를 보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
 
void swap(int &num1, int &num2)
{
    int temp = num1;
    num1 = num2;
    num2 = temp;
}
void main()
{
    int a = 20, b = 60;
    swap(a, b);
    printf("a: %d, b: %d", a, b);
    // 출력 결과 - a: 60, b: 20
}
cs

pass by reference 방식을 사용했기 때문에 함수 내에서 값이 바뀌면 원래 값도 바뀌게 된다. 

Pass by Result

1. Pass by result는 함수의 파라미터로 전해진 변수에 함수 내에서의 결과를 반환하는 방식이다.

2. 함수로 파라미터를 전달할 때 아무 값도 전달되지 않는다.

3. 반대로 함수내에서의 결괏값을 파라미터로 전달하여 원래 값에 영향을 준다. 

 

이해가 쉽지 않다면 다음 예시를 보자. ( pass by result가 적용된 언어라고 가정하자 )

1
2
3
4
5
6
7
8
9
10
11
12
void sub(int x)
{
    x = 30;
}
 
void main()
{
    int a = 20;
    sub(a);
    printf("a: %d", a);
    // 출력 결과 - a: 30
}
cs

sub(int x) 함수 내에서 x값을 변경하면 해당 값을 복사해서 파라미터로 전달한 변수에 넣어준다.

즉, 파라미터를 함수로 전달한다기 보다는 함수에서 파라미터로 결과를 전달하는 것이다.

 

이 방식은 큰 문제가 발생한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
void sub(int a, int b)
{
    a = 30;
    b = 40;
}
 
void main()
{
    int x = 20;
    sub(x, x);
    printf("x: %d", x);
    // 출력 결과 - x: 30? 40?
}
cs

예를 들어 위와 같은 상황이 발생하면, x의 값이 30이 될지 40이 될지 알 수 없는 오류가 발생한다.

Pass by value-result

1. pass by value 방식과 pass by result 방식이 합쳐진 방식이다.

2. 함수로 파라미터의 값을 pass by value 방식으로 전달하고

3. 함수에서 파라미터로 값을 pass by result 방식으로 반환하는 방식이다.

Pass by name

1. pass by name은 변수를 파라미터로 전달한다면 pass by reference처럼 작동한다.

2. 변하지 않는 상수값(constant)을 전달한다면 pass by value처럼 작동한다.

3. Array(배열)이라면 해당 배열에 assignment가 발생하면 binding 된다. (이해가 어렵다면 넘어가자)

4. 이해하기 힘들고 판독하기 힘든 방식이다. 

 

반응형

댓글

Designed by JB FACTORY