티스토리 뷰

반응형
C++ 참조자에 의한 인수 전달 완벽 정리

✅ C++에서 참조자에 의한 인수 전달: 복사 없이 값을 바꾸는 똑똑한 방법

C++에서 함수에 값을 넘겨줄 땐, 결과가 달라질 수 있습니다.
눈에 보이지 않게 프로그램 속에서 "복사"가 일어나기 때문입니다.

다음과 같은 코드에서 어떤 결과가 나올까요?

void modify(int x) {
    x = 100;
}

int main() {
    int a = 10;
    modify(a);
    cout << a << endl;  // ?
}

결과는 a가 그대로 10입니다. 함수에서 x = 100;을 했지만,
a의 값은 바뀌지 않았습니다. 왜냐하면 modify(a) 호출 시 a의 복사본이 함수로 전달되었기 때문입니다.

그렇다면, 함수에서 변수의 값을 진짜로 바꾸려면 어떻게 해야 할까요?
복사본이 아니라, 변수 그 자체를 전달하는 방법이 필요합니다.
여기서 등장하는 개념이 바로 참조자(reference)입니다.



🔍 참조자에 의한 인수 전달이란?

C++에서는 변수 자체를 함수로 넘기는 방식으로 참조자(reference)를 사용할 수 있습니다.
참조자에 의한 인수 전달은, 함수가 매개변수로 전달받은 값을 복사하지 않고
원래 변수 그 자체에 별명을 붙여 직접 접근하는 방식입니다.

void modify(int& x) {
    x = 100;
}

이제 modify(a);를 호출하면, xa의 또 다른 이름이 되므로, x = 100;은 곧 a = 100;입니다.
이런 식으로 함수에서 변수의 원본을 직접 조작할 수 있게 됩니다.



💡 왜 복사하지 않는 게 중요할까?

변수를 복사해서 함수로 넘기는 건 간단해 보이지만,
그 복사가 비용이 크다면 문제가 달라집니다.

  • 구조체나 클래스 객체처럼 덩치가 큰 데이터는 복사 시간이 오래 걸릴 수 있습니다.
  • 값만 넘겨줄 수 있으면 좋은데, 그 값은 절대 바뀌면 안 되는 경우도 있죠.

이럴 때 참조자를 쓰면 복사 없이도 데이터를 다룰 수 있고,
필요하면 const를 붙여 원본이 바뀌지 않도록 제어할 수 있습니다.



🧪 예제로 보는 참조자 인자 전달

#include <iostream>
using namespace std;

void increase(int& value) {
    cout << "[함수] 주소: " << &value << ", 값: " << value << endl;
    value += 10;
}

int main() {
    int score = 70;
    cout << "[main] 주소: " << &score << ", 값: " << score << endl;
    increase(score);
    cout << "[main] 함수 호출 후 값: " << score << endl;
    return 0;
}

🧾 출력 결과

[main] 주소: 0x61fdf4, 값: 70  
[함수] 주소: 0x61fdf4, 값: 70  
[main] 함수 호출 후 값: 80

📌 함수에 전달된 valuescore같은 주소를 가리킵니다.
즉, value를 바꾸면 score도 함께 바뀝니다.



🔒 원본은 넘기되, 절대 수정되면 안 될 때는?

참조자를 통해 데이터를 복사 없이 넘기고 싶지만,
실수로 값을 바꾸는 일이 생기면 안 되는 상황도 많습니다.

그럴 땐 const를 붙여서 읽기 전용 참조자를 만들 수 있습니다.

void print(const string& message) {
    cout << "메시지: " << message << endl;
}

이 방식은 다음과 같은 이점을 줍니다:

  • 문자열 같은 크기가 큰 자료형을 복사하지 않고 성능을 지킬 수 있고
  • 임시 객체도 받을 수 있습니다
    print("hello") 호출 가능 (임시로 생성된 string을 참조함)


🧠 그렇다면 const 참조자는 값 전달보다 항상 좋을까?

많은 사람들이 이렇게 생각합니다:

“복사도 안 되고, 수정도 안 되니까 const 참조자면 무조건 낫지 않나요?”

하지만 꼭 그렇지만은 않습니다.
특히 int, char, bool 같은 작은 타입이라면 오히려
값 전달이 더 빠르고 간단할 수 있습니다.

void func(int x);               // 값 전달 → 빠름
void func(const int& x);      // 참조자 → 느릴 수 있음

📌 이유: 작은 타입은 복사가 매우 빠르며, 컴파일러는 레지스터로 처리합니다.
하지만 참조자는 메모리를 거쳐 접근해야 하므로 오히려 비용이 발생할 수 있습니다.



🔁 복사 vs 참조: 코드로 직접 비교

#include <iostream>
using namespace std;

void byValue(int x) {
    x = 999;
}

void byReference(int& x) {
    x = 888;
}

int main() {
    int n = 100;
    byValue(n);
    cout << "[byValue 후] n: " << n << endl;

    byReference(n);
    cout << "[byReference 후] n: " << n << endl;
    return 0;
}

🧾 출력 결과

[byValue 후] n: 100  
[byReference 후] n: 888
  • byValue복사본을 바꾸므로 원본 불변
  • byReference원본을 직접 수정합니다


✅ 참조자 인자 전달을 써야 하는 경우

상황 참조자 사용 권장 여부
함수에서 값을 바꾸고 싶을 때 ✅ 사용해야 함
큰 객체 전달 (복사 비용이 클 때) ✅ 필수
값은 넘기되 변경되면 안 될 때 ✅ const 사용
작은 타입(int, char 등) 전달 시 ❌ 값 전달이 더 효율적


📚 정리하며

참조자는 C++에서 가장 강력하면서도 섬세한 기능 중 하나입니다.
그 자체로는 단순해 보여도, 함수 호출 방식, 성능, 코드 안정성에 큰 영향을 미칠 수 있습니다.

  • 값을 바꾸고 싶다면 참조자
  • 복사 없이 읽기만 하고 싶다면 const 참조자
  • 데이터가 작고 변경도 필요 없다면 값 전달

상황에 맞춰 쓰는 것이 정답입니다.
도구는 많지만, 어디에 써야 할지를 아는 것이 진짜 실력입니다.

반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/11   »
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 29
30
글 보관함
반응형