Notice
Recent Posts
Recent Comments
«   2025/02   »
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
Archives
Today
Total
관리 메뉴

SYDev

C++ Chapter 02-4 : 함수에서의 참조자(Reference)(1) 본문

Programming Lang/C++

C++ Chapter 02-4 : 함수에서의 참조자(Reference)(1)

시데브 2023. 7. 10. 19:12

함수에서의 참조자

 참조자는 다음과 같이 함수에서 매개변수로 선언될 수 있다. 

void MyFunc(int &ref1, int &ref2)
{
.
.
.
}

 지난 게시물 C++ Chapter 02-3 : 참조자(Reference)에 따르면 참조자는 선언과 동시에 초기화돼야 한다는 것을 기억할 것이다. 그렇다면 위 구조는 어떻게 가능한 것일까?

 

 매개변수는 함수가 호출되는 동시에 초기화가 진행되는 변수들이다. 즉, 함수에 인자를 입력하면 해당 변수의 참조자로서 ref1, ref2가 선언과 동시에 초기화되는 것이다.

 

 그렇다면 이렇게 선언된 참조자는 함수에서 어떻게 사용될까? 이를 알기 위해서는 call-by-value와 call-by-reference를 먼저 이해해야 한다.

Call-by-value & Call-by-reference

Call-by-value

 Call-by-value는 값을 인자로 전달하는 함수의 호출방식을 말한다. 함수 호출 시에 넘기는 인자의 값이 매개변수에 복사되어 그 매개변수를 함수 내에서 어떤 변화를 주어도 처음 전달한 인자에는 아무 영향을 주지 못한다.

 

 다음 예제를 살펴보자.

#include <iostream>
using namespace std;

void Swap(int a, int b)
{
    int tmp = a;
    a = b;
    b = tmp;
}

int main(void)
{
    int x = 10;
    int y = 20;

    cout<<x<<" "<<y<<endl;
    Swap(x,y);
    cout<<x<<" "<<y<<endl;

    return 0;
}
10 20
10 20

 int 변수 x,y가 Swap함수에 들어가도 변하지 않았다. Swap함수가 호출될 때에 정수 x,y 값은 매개변수 a,b에 각각 복사된다. 이 때문에 Swap 함수에서 어떤 변화가 있어도 x,y의 값에 영향을 주지 못한다.

 

Call-by-reference

 Call-by-value는 주소 값을 인자로 전달하는 함수의 호출방식이다. 인자를 복사하여 매개변수에 입력되는 것은 Call-by-value와 같지만 복사되는 인자값이 데이터의 주소값이기 때문에 전달한 인자의 데이터 값에 영향을 줄 수 있다.

 

 다음 예제를 살펴보자.

#include <iostream>
using namespace std;

void Swap(int* a, int* b) // 포인터 변수형을 인자로 받겠다 선언
{
    int tmp = *a;
    *a = *b;
    *b = tmp;
}

int main(void)
{
    int x = 10;
    int y = 20;

    cout<<x<<" "<<y<<endl;
    Swap(&x,&y); // 받는 인자의 형태가 포인터(주소)이기 때문에 x,y 앞에 & 입력
    cout<<x<<" "<<y<<endl;

    return 0;
}
10 20
20 10

연산자 *로 포인터 개념을 사용하여 주소에 직접적으로 접근할 수 있게 되었기 때문에 Swap 함수 외부에도 영향을 끼칠 수 있게 되었다.

 

참조자(&)를 이용한 Call-by-reference

 call-by-reference는 위와 같이 포인터를 이용한 방식 외에도 참조자를 이용하는 방식도 있다.

 

 이와 관련하여 다음 예제를 살펴보자.

#include <iostream>
using namespace std;

void SwapByRef2(int &ref1, int &ref2)
{
    int temp = ref1;
    ref1 = ref2;
    ref2 = temp;
}

int main(void)
{
    int x = 10;
    int y = 20;

    SwapByRef2(x, y);
    cout<<x<<endl;
    cout<<y<<endl;

    return 0;
}
20
10

 위 예제를 통해서 참조자를 이용하면 함수 내에서 정수 x와 y의 주소에 직접 접근할 수 있음을 알게되었다. 이게 어떻게 가능한 것인지는 위 call-by-value와 참조자를 이용한 call-by-reference 코드에 간단한 문장만을 추가하여 알 수 있다. 

 

#include <iostream>
using namespace std;

void Swap(int a, int b)
{
    cout<<"a의 주소 :"<<&a<<endl;
    cout<<"b의 주소 :"<<&b<<endl;

    int tmp = a;
    a = b;
    b = tmp;
}

int main(void)
{
    int x = 10;
    int y = 20;


    cout<<"x의 주소 :"<<&x<<endl;
    cout<<"y의 주소 :"<<&y<<endl;    
    Swap(x,y);

    return 0;
}
x의 주소 :0x61fe1c
y의 주소 :0x61fe18
a의 주소 :0x61fdf0
b의 주소 :0x61fdf8

 위 예제를 통해 call-by-value에서는 지역번수 x,y와 a,b의 주소가 다름을 알 수 있다.

#include <iostream>
using namespace std;

void SwapByRef2(int &ref1, int &ref2)
{
    cout<<"ref1의 주소:"<<&ref1<<endl;
    cout<<"ref1의 주소:"<<&ref2<<endl;

    int temp = ref1;
    ref1 = ref2;
    ref2 = temp;
}

int main(void)
{
    int x = 10;
    int y = 20;

    cout<<"x의 주소:"<<&x<<endl;
    cout<<"y의 주소:"<<&y<<endl;

    SwapByRef2(x, y);

    return 0;
}
x의 주소:0x61fe1c
y의 주소:0x61fe18
ref1의 주소:0x61fe1c
ref2의 주소:0x61fe18

 반면 매개변수에 참조자의 선언을 이용하면 다음과 같이 입력하는 인자 x, y와 함수의 매개변수이자 참조자인 ref1, ref2의 주소가 같다.

 

 이를 통해서 함수를 선언할 때 매개변수에 참조자를 이용하면 입력받는 인자의 주소에 직접 접근하여 변화를 줄 수 있다는 것을 알 수 있다. 


참고자료

 

[C, C++] Call by value, Call by reference 쉽게 이해하기

인트로 (본 포스팅은 포인터와 관련이 깊습니다.) 함수의 호출 방법은 대표적으로 Call by value(값에 의한 호출)와 Call by reference(참조에 의한 호출)가 있다. 함수 호출이란 말 그대로 정의된 함수를

kangworld.tistory.com

 

C++ 강의 7장 - 참조자(Reference) -

C++ 강의 7장- 참조자(Reference) - 변수라고 하는 것은 할당된 메모리 공간에 붙여진 이름이다. 우리는 이 이름을 가지고 해당 메모리 공간에 접근이 가능해진다. 그러면 참조자는 무엇일까? 참조자

copycode.tistory.com

  • 윤성우, <윤성우의 열혈 C++ 프로그래밍>, 오렌지미디어, 2010.05.12