강께르의 개발일지

[C++] Call by value / address / reference 본문

프로그래밍/C++

[C++] Call by value / address / reference

강께르 2021. 6. 9. 12:10

 이 글에서 설명할 Call by value / address / reference는 '함수가 호출될 때, 매개변수를 어떤 방식으로 전달할 것이냐?'에 대한 방법들이다. 앞에서부터 차례대로 한글로 번역하자면 '값에 의한 호출', '주소에 의한 호출', 참조에 의한 호출'이라고 할 수 있다.

 

1. Call by value(값에 의한 호출)

- Call by value는 함수를 호출하여 매개변수를 호출된 함수에게 전달할 때, 값의 복사로 전달을 하겠다는 방식이다.

- 값이 복사되어 전달되어 그 값으로 초기화된 매개변수는 전달되기 이전의 변수와는 완전히 별개의 변수다.

- 그래서 함수 내에서 아무리 매개변수를 조작해도 전달되기 이전의 그 변수하고 다르기 때문에 어떠한 변경이 없다.

int num = 10;
func(num);
cout << num;		// 출력결과 10

void func(int val)
{
    val = 15;
    cout << val; 	// 출력결과 15
}			// 함수에서 변경점은 함수에서만 유효

- 위에 보이는 코드와 같이 num의 값이 15가 바뀌어지길 기대하고 있지만 이는 Call by value 방식의 매개변수 전달이어서 15로 바뀌는 val은 함수 내에서만 유효하고 num은 그대로 10이라는 값을 출력할 것이다.

 

2. Call by address

- Call by address는 함수를 호출하여 매개변수를 호출된 함수에게 전달할 때, 변수의 주소값을 전달을 하겠다는 방식이다.

- 매개변수에는 변수의 값이 저장되는 것이 아닌 전달하고자 하는 변수의 주소값이 저장되기에 함수에서 직접 그 변수를 접근할 수 있다는 것이다.

- 접근할 수 있다는 것을 이용해서 함수 내에서 매개변수로 전달받은 변수의 값을 변경하거나 새로 대입하는 등 변경을 할 수 있다.

int num = 10;
func(&num);
cout << num;		// 출력결과 15

void func(int* val)
{
    *val = 15;
    cout << *val; 	// 출력결과 15
}			// 함수에서 직접 변수에 접근, 변경 가능

- 위에 보이는 코드와 같이 num의 값이 Call by value에서는 10이라는 출력값을 보여줬지만, 함수의 매개변수로 주소값을 받아 직접 그 주소에 있는 값을 변경을 했기에 함수 내에서 *val의 값 15가 num의 값이 된 것이다.

 

3. Call by reference

- Call by reference는 C++에서 지원한다. 이는 함수를 호출하여 매개변수를 참조자 선언해, 값이나 주소값을 전달하는 것이 아닌 전달할 변수의 참조변수로 전달을 하겠다는 방식이다.

- 매개변수에는 주소값을 저장하는 포인터 변수나 값을 가지는 일반 변수처럼 메모리 공간을 할당을 받는 것이 메모리 공간을 차지하지 않고 참조하려는 변수의 일종의 별명을 가져 참조하려는 변수의 메모리를 공유하는 레퍼런스 변수를 사용하기에 Call by address와는 코드 작성은 약간 다르지만 해당 변수를 변경할 수 있다는 점은 동일하다.

int num = 10;
func(num);		// 참조변수여서 이름만 줘도 된다.
cout << num;		// 출력결과 15

void func(int& val)
{
    val = 15;		// 역참조를 사용하지 않아도 접근 가능
    cout << val; 	// 출력결과 15
}			

- 위와 같이 Call by address처럼 매개변수를 포인터 변수로 선언하지 않고 레퍼런스 변수, 참조 변수를 선언함으로써 역참조에 대한 부담을 덜며 값을 수정할 수 있는 특징이 있다.

 

4. Call by address와 Call by reference의 차이

- 위 둘은 해당 변수의 주소에 접근하여 값을 수정할 수 있는 점은 똑같다.

- 하지만 address는 매개변수가 포인터 변수로 선언되어 포인터 변수에 주소값을 저장하기 위한 메모리 4바이트를 차지해야하고 reference는 매개변수가 참조 변수로 선언되어 변수 자체를 참조하기에 참조하려는 변수의 메모리를 공유하며 따로 주소값 같은 것을 저장하지 않아 메모리 할당을 받지 않는다.

- address는 포인터를 다룬다는 것으로 특징을 지니고 있다.