Computer >> 컴퓨터 >  >> 프로그래밍 >> C 프로그래밍

C/C++ 매개변수 전달 방식 3가지 총정리: 값 호출, 주소 호출, 참조 호출

C 언어에서는 함수에 매개변수를 전달하는 방법이 크게 두 가지 있습니다. 바로 값에 의한 호출(Call by Value)주소에 의한 호출(Call by Address)입니다. 여기에 C++에서는 한 가지 기법이 더 추가되는데, 바로 참조에 의한 호출(Call by Reference)입니다. 이번 글에서는 이 세 가지 방식이 각각 어떻게 동작하며, 어떤 차이가 있는지 예제 코드를 통해 자세히 살펴보겠습니다.

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

값에 의한 호출은 가장 기본적인 매개변수 전달 방식입니다. 이 방식에서는 함수를 호출할 때 인자의 복사본이 함수의 매개변수로 전달됩니다. 따라서 함수 내부에서 매개변수 값을 아무리 수정해도, 변경되는 것은 복사된 값일 뿐 원래 변수의 값은 그대로 유지됩니다.

아래 예제는 두 변수의 값을 서로 교환(swap)하려는 코드입니다.

예제 코드

#include <iostream>
using namespace std;
void my_swap(int x, int y) {
    int temp;
    temp = x;
    x = y;
    y = temp;
}
int main() {
    int a, b;
    a = 10;
    b = 40;
    cout << "(a,b) = (" << a << ", " << b << ")\n";
    my_swap(a, b);
    cout << "(a,b) = (" << a << ", " << b << ")\n";
}

실행 결과

(a,b) = (10, 40)
(a,b) = (10, 40)

실행 결과를 보면 my_swap() 함수를 호출했음에도 불구하고 ab의 값이 그대로 10과 40으로 출력됩니다. 함수 내부에서는 값이 실제로 교환되었지만, 그 대상은 복사된 지역 변수 xy였기 때문에 원본에는 아무런 영향을 주지 못한 것입니다.

2. 주소에 의한 호출 (Call by Address)

주소에 의한 호출은 변수 자체가 아니라 변수의 메모리 주소(포인터)를 함수에 전달하는 방식입니다. 함수 내부에서 해당 주소가 가리키는 값을 역참조(*)하여 수정하면, 원본 변수의 값도 함께 변경됩니다.

예제 코드

#include <iostream>
using namespace std;
void my_swap(int *x, int *y) {
    int temp;
    temp = *x;
    *x = *y;
    *y = temp;
}
int main() {
    int a, b;
    a = 10;
    b = 40;
    cout << "(a,b) = (" << a << ", " << b << ")\n";
    my_swap(&a, &b);
    cout << "(a,b) = (" << a << ", " << b << ")\n";
}

실행 결과

(a,b) = (10, 40)
(a,b) = (40, 10)

이번에는 호출 시 &a, &b처럼 변수의 주소를 넘겼고, 함수 내부에서 포인터를 통해 원본 메모리에 직접 접근했기 때문에 두 값이 성공적으로 교환된 것을 확인할 수 있습니다.

3. 참조에 의한 호출 (Call by Reference)

참조에 의한 호출은 C++에서만 제공되는 고유 기능입니다. 함수의 매개변수를 참조 변수(reference variable)로 선언하면, 함수 내부에서 사용하는 이름이 곧 원본 변수의 별명(alias)처럼 동작합니다. 따라서 함수 안에서 값을 수정하면 원본 값이 직접 변경됩니다.

문법적으로는 함수 정의 부분에서 매개변수 이름 앞에 &만 붙여주면 됩니다. 호출부는 값에 의한 호출과 완전히 동일하게 작성할 수 있어, 주소에 의한 호출보다 코드가 훨씬 깔끔하다는 장점이 있습니다.

예제 코드

#include <iostream>
using namespace std;
void my_swap(int &x, int &y) {
    int temp;
    temp = x;
    x = y;
    y = temp;
}
int main() {
    int a, b;
    a = 10;
    b = 40;
    cout << "(a,b) = (" << a << ", " << b << ")\n";
    my_swap(a, b);
    cout << "(a,b) = (" << a << ", " << b << ")\n";
}

실행 결과

(a,b) = (10, 40)
(a,b) = (40, 10)

호출부는 첫 번째 예제와 똑같은데도 값이 성공적으로 교환되었습니다. 이는 매개변수 xy가 각각 ab의 참조(별명)로 동작하기 때문입니다.

세 가지 방식 비교 요약

전달 방식 전달되는 것 원본 값 변경 여부 지원 언어
값에 의한 호출 값의 복사본 변경되지 않음 C, C++
주소에 의한 호출 변수의 메모리 주소 변경 가능 C, C++
참조에 의한 호출 원본 변수의 참조 변경 가능 C++ 전용

정리하면, 함수가 원본 데이터를 수정해야 한다면 주소에 의한 호출 또는 참조에 의한 호출을 사용해야 하며, 원본 보호가 필요하다면 값에 의한 호출이 적합합니다. 특히 C++에서는 문법이 간결하고 안전한 참조에 의한 호출이 일반적으로 권장됩니다.