티스토리 뷰
[C / C++] Call by value(값에 의한 호출), Call by Reference(참조에 의한 호출), 무엇이 다르지?
whatisyourname 2022. 5. 11. 11:45컴퓨터과학에서 함수와 관련된 부분을 보면 call by value(값에 의한 호출), call by reference(참조에 의한 호출)이라는 개념을 마주칠 때 있다.
C / C++ 언어 계열은 포인터라는 엄청난 기능 덕분에 직접 메모리에 접근할 수 있기에 두 가지 방법 모두 사용이 가능하고, 다른 특징을 가진다.
C++에서 사용되는 두 가지 방법을 간략하게 알아보도록 하자.
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; *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 : 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
- 함수의 매개변수에 변수가 복사되어 들어간다.
- 함수 내에서 생긴 변화는 다른 함수에 영향을 주지 못한다.
- 매개변수를 담은 공간과 실제 변수의 공간은 다른 메모리 주소를 가진다.
2) call by reference
- 함수의 매개변수에 변수의 주소가 들어간다.
- 함수 내에서 생긴 변화가 다른 함수에 영향을 줄 수 있다.
- 매개변수를 담은 공간과 실제 변수의 공간은 같은 메모리 주소를 가진다.
4. 다른 언어에서는?
다른 언어에서도 직접 메모리를 조작할 수 있다면 call by value, call by reference의 방법으로 함수의 매개변수에 인자를 전달할 수 있다. 다만, 메모리에 직접 접근하지 못하는 언어의 경우에는 자료형에 따라 언어가 자동으로 결정하거나, 파이썬과 같이 call by assignment라는 독특한 체계를 갖기도 한다. 자바의 경우는 call by value만 존재한다.
'C++' 카테고리의 다른 글
[C / C++] return 0; 는 왜 종료의 표준이 되었나? 프로그램 종료에 대한 이해 (1) | 2022.04.25 |
---|---|
[C++] for문과는 조금 다른 활용? for_each 함수를 활용하여보자. (1) | 2022.04.21 |
[C++] 두 배열을 함수 한 방에 아주 쉽게 비교하자! equal (0) | 2022.04.17 |
[C++] 배열 안을 함수 한 번에 회전시켜보자! rotate (0) | 2022.04.17 |
[C++] 누적 합을 함수 한 방에 구하여보자! partial_sum (0) | 2022.04.14 |
- Total
- Today
- Yesterday
- C++
- 구현
- 알고리즘
- 백준
- BOJ
- 프로그래밍
- bomblab
- react
- docker
- CSAPP
- BRONZE
- JS
- equal
- Network
- effective async
- MIN
- Proactor
- 문자열
- Max
- 사칙연산
- for
- 시간복잡도
- 헤더
- GDSC
- C
- Python
- 제어문
- 수학
- 함수
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |