티스토리 뷰

반응형

컴퓨터과학에서 함수와 관련된 부분을 보면 call by value(값에 의한 호출), call by reference(참조에 의한 호출)이라는 개념을 마주칠 때 있다.

 

C / C++ 언어 계열은 포인터라는 엄청난 기능 덕분에 직접 메모리에 접근할 수 있기에 두 가지 방법 모두 사용이 가능하고, 다른 특징을 가진다.

 

C++에서 사용되는 두 가지 방법을 간략하게 알아보도록 하자.

thumbnail
call by value vs call by reference


1. Call by Value : 값에 의한 호출

Call by value는 함수 호출 스택에서 매개변수를 저장하는 공간에 인자를 저장하는 방법으로 인자가 함수에게 전달되는 방식이다.

 

다른 말로, 인자로 넘겨진 값이 변경되어도 그 함수에서만 변경된다는 의미이다.

 

예제를 살펴보도록 하자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream> // cout
using namespace std;
 
void change(int num) {
    num = 5;
}
 
int main() {
 
    int data = 0;
    change(data);
    cout << data;
    // cout : 0
 
    return 0;
}
cs

 

void change에서 인자(num)의 값을 바꾸었지만, 넘겨준 data의 값은 그대로 인 것을 확인할 수 있다.

 

이는 num의 값에 data의 값을 복사한 뒤 num의 값에 5를 넣어주었기 때문에, 원본의 data에는 영향을 미치지 않는 것이다.

 

따라서, 원본의 data의 값인 0이 출력되는 것이다.

 

다른 예시를 들어보도록 하자. 매우 유명한 예제이다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream> // cout
using namespace std;
 
void swap(int x, int y) {
    int temp;
    temp = x;
    x = y;
    y = temp;
}
 
int main() {
 
    int x = 100, y = 200;
    swap(x, y);
    cout << "Value of x : " << x << endl;
    cout << "Value of y : " << y << endl;
 
    // Value of x : 100
    // Value of y : 200
 
    return 0;
}
cs

 

이 경우 swap함수에서 x, y를 바꾸었지만, 주소 값을 넘겨주지 않고 값만 넘겨주었기에 call by value, 즉 값에 의한 참조로 함수가 작동한다. 따라서 x와 y에 각각 100과 200이 복사되었고 함수 스택 내부에서는 둘의 값이 바뀌었지만, 함수 밖에 영역에는 영향을 미치지 못한다.


2. Call by Reference : 참조에 의한 호출

Call by reference는 call by value와 다르게 함수를 넘겨줄 때 메모리의 주소로 넘겨준다. 즉, 참조(*)의 형태 혹은 역참조(&)의 형태로 넘겨준다는 의미이다.

 

메모리에 직접 함수가 접근하기에 메모리의 값을 변경하면 함수 밖의 영역에도 영향을 미친다고 할 수 있다.

 

위의 예시에서 swap 함수가 제대로 작동되지 않았으므로, 이를 call by reference로 바꾸어서 정상적으로 작동하도록 하자.

 

swap에서는 직접 메모리 주소로 변수에 접근하여 교환을 진행하였다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream> // cout
using namespace std;
 
void swap(int *x, int *y) {
    int temp;
    temp = *x;
    *= *y;
    *= temp;
}
 
int main() {
 
    int x = 100, y = 200;
    swap(&x, &y);
    cout << "Value of x : " << x << endl;
    cout << "Value of y : " << y << endl;
 
    // Value of x : 200
    // Value of y : 100
 
    return 0;
}
cs

 

call by value와 다른 점을 하나씩 꼽아보자.

 

먼저, swap의 매개변수가 값이 아닌, 포인터의 형태, 즉 메모리 주소를 받도록 하였다. 따라서 직접 변수들의 메모리에 접근을 할 수 있게 되었고, 교환 시 메모리에서 직접 교환을 하는 것이기 때문에 x와 y의 값이 바뀌는 것이다.


3. 결론

정리하자면 call by value와 call by reference는 다음과 같은 차이를 보인다.

1) call by value

  1. 함수의 매개변수에 변수가 복사되어 들어간다.
  2. 함수 내에서 생긴 변화는 다른 함수에 영향을 주지 못한다.
  3. 매개변수를 담은 공간과 실제 변수의 공간은 다른 메모리 주소를 가진다.

2) call by reference

  1. 함수의 매개변수에 변수의 주소가 들어간다.
  2. 함수 내에서 생긴 변화가 다른 함수에 영향을 줄 수 있다.
  3. 매개변수를 담은 공간과 실제 변수의 공간은 같은 메모리 주소를 가진다.

4. 다른 언어에서는?

다른 언어에서도 직접 메모리를 조작할 수 있다면 call by value, call by reference의 방법으로 함수의 매개변수에 인자를 전달할 수 있다. 다만, 메모리에 직접 접근하지 못하는 언어의 경우에는 자료형에 따라 언어가 자동으로 결정하거나, 파이썬과 같이 call by assignment라는 독특한 체계를 갖기도 한다. 자바의 경우는 call by value만 존재한다.

반응형
댓글
Total
Today
Yesterday
공지사항
최근에 올라온 글
최근에 달린 댓글
링크
«   2024/05   »
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 31
글 보관함