PS(Problem Solving)/CPP 개념, stl 정리

[CPP] call by address, reference, value

LiaLi_1997 2021. 10. 27. 12:11

이번에 NHN 신입공채 코테를 보게 되었는데 입출력이 평소에 풀던 거랑 달라서 많이 헤메었다.

또한 PS 문제를 풀고 나서 다른 사람의 소스를 보는데 함수에서 매개변수 호출 할 때 referece 호출이 많아서 이걸 정리해 보려 한다.


1. call by value

제일 기본적으로 값 자체를 받는 경우이다. 이러한 방식은 문제가 발생하는데 아래의 예시를 보자

#include <iostream>

using namespace std;

void swap(int A, int B) {
    int tmp;
    tmp = B;
    B = A;
    A = tmp;
}

int main(void) {
    int A = 10;
    int B = 30;

    swap(A, B);

    cout << A << '\n' << B;

    return 0;
}

위의 코드를 실행 했을 때 예상 결과값은 30 10 이다.
하지만 실제로는 10 30 으로 예상과는 다르다. 이는 함수를 호출하는 과정에서 쌓이는 스택때문에 그런데 아래를 보면 이해가 될 것이다.

기본적으로 모든 변수와 함수는 스택 구조로 쌓이고 함수단위로 pop 이 되기 때문에 이러한 현상이 발생한다.

2. call by address

call by address 란 주소로 매개변수로 받는것을 말한다.

#include <iostream>

using namespace std;

void swap(int *A, int *B) {
    int tmp;
    tmp = *B;
    *B = *A;
    *A = tmp;
}

int main(void) {
    int A = 10;
    int B = 30;

    swap(&A, &B);

    cout << A << '\n' << B;

    return 0;
}
int* A = &k // k 는 주소 값만 들어갈 수 있다.
int& A = k // k 는 A 의 값이 들어가게 되는데 이 때 A와 k 의 주소값이 같아진다.

위의 Call By Address 는 단점이 명확하다.
1. 변수의 메모리에 직접 접근하기 때문에 다른 코드 혹은 시스템을 건드릴 위험이 존재한다.
2. 포인터 연산은 헷갈리므로 PS 를 할 때 지양하는 것이 좋다.

3. Call By Reference

call by reference 는 cpp 에서만 가능한 기능으로(c 에서 불가) call by address 에 비해 혼동할 염려가 적다.

#include <iostream>

using namespace std;

void swap(int &AA, int &BB) {
    int tmp;
    tmp = AA;
    AA = BB;
    BB = tmp;
}

int main(void) {
    int A = 10;
    int B = 30;
    swap(A, B);   

    cout << A << '\n' << B << '\n';

    return 0;
}

위의 도식에서도 알 수 있듯이 A 와 AA 가 같은 주소를 공유한다. 따라서 안에 있는 값을 참조할 때도 같은 값을 참조하게 된다.

정리

Call by value, call by address, call by reference 를 알아보았다. 정리하자면 아래와 같다.
1. call by value 는 변수 참조가 문제가 될 수 있기 때문에 다른 함수 안에서 변수를 변경하는 것은 문제가 생길 수 있다.
2. call by address 는 참조를 가능하게 할 수는 있다. 하지만 메모리 직접 접근이기에 주의를 기울여야 하므로 지양하는 것이 좋다.
3. call by referece 는 변경하고자 하는 변수에 별명을 지어준다고 생각하면 편하다. 왠만하면 call by reference 를 쓰는 것을 추천한다.