C++

2024.02.27 - 인수 전달

강병곤 2024. 2. 27. 18:41

함수를 통해서 매개변수로 전달한 변수의 값을 바꾸고 싶다.

그래서 아래와 같은 코드를 만들어 보았다.

#include<iostream>

void Value(int n) {
    n = 10;
}

int main() {
    int num = 30;
    Value(num);
    std::cout << "num 값: " << num << std::endl;
}

생각대로라면, num은 Value()함수에 매개변수로 전달되어 10으로 초기화되니 num의 값은 10이 될 것이다.

 

그러나 num값은 바뀌지 않았다.

 

왜 이런 일이 일어 났는지 이해하기 위해서는 아래와 같은 코드를 살펴볼 필요가 있다.

  • 값에 의한 전달(call by value) 
#include<iostream>

void Value(int n) {
    n = 10;
    std::cout << "n의 값: " << n << std::endl;
    std::cout << "n의 주소값: " << &n << std::endl;
}

int main() {
    int num = 30;
    Value(num);
    std::cout << "num 값: " << num << std::endl;
    std::cout << "num 주소값: " << &num << std::endl;
}

Value()함수의 매개변수 n은 num과 다른 메모리 주소를 할당 받기 때문에 둘은 완전히 다른 변수이다. n에 num값인 30이 전달되었지만, n값이 10으로 바뀐다고 해서 num값이 바뀌지는 않는다.

 

그러면 num의 값을 바꾸기 위해선 어떻게 해야할까?

 

포인터를 사용하여 주소값을 받아 역참조로 해당 변수의 값을 바꾸는 방법이 있다.

  • 주소에 의한 전달 (call by address)
#include<iostream>

void Address(int* n) {
    *n = 10;
    std::cout << "포인터 n의 값: " << n << std::endl;
    std::cout << "포인터 n의 주소값: " << &n << std::endl;
    std::cout << "포인터 n이 가리키는 값: " << *n << std::endl;
}

int main() {
    int num = 30;
    Address(&num);
    std::cout << "num 값: " << num << std::endl;
    std::cout << "num 주소값: " << &num << std::endl;
}

Address()함수의 매개변수로 포인터 변수n을 사용하여, num의 주소값인 &num을 주었다.

포인터를 이용한 역참조는 해당 주소의 메모리의 값에 바로 접근할 수 있기 때문에 함수안에서 값을 바꿔도 동작한다.

 

  • 참조에 의한 전달(call by reference)
#include<iostream>

void Reference(int& n) {
    n = 10;
    std::cout << "n의 값: " << n << std::endl;
    std::cout << "n의 주소값: " << &n << std::endl;
}

int main() {
    int num = 30;
    Reference(num);
    std::cout << "num 값: " << num << std::endl;
    std::cout << "num 주소값: " << &num << std::endl;
}

 

Reference()함수를 실행할 때 내부적으로 int& n = num;이 실행된다. &연산자는 변수타입과 변수명 사이에 붙으면 별명(참조자)를 선언한다는 뜻이 된다. 매개 변수 x는 a의 별명이 되어 a와 같은 메모리 주소값을 가진다. (x와 a의 주소가 같다) 따라서 x의 값을 변경하는 것으로 a의 값을 변경할 수 있다.