티스토리 뷰
✅ 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);를 호출하면, x는 a의 또 다른 이름이 되므로, 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
📌 함수에 전달된 value와 score는 같은 주소를 가리킵니다.
즉, 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는 원본을 직접 수정합니다
✅ 참조자 인자 전달을 써야 하는 경우
📚 정리하며
참조자는 C++에서 가장 강력하면서도 섬세한 기능 중 하나입니다.
그 자체로는 단순해 보여도, 함수 호출 방식, 성능, 코드 안정성에 큰 영향을 미칠 수 있습니다.
- 값을 바꾸고 싶다면 참조자
- 복사 없이 읽기만 하고 싶다면 const 참조자
- 데이터가 작고 변경도 필요 없다면 값 전달
상황에 맞춰 쓰는 것이 정답입니다.
도구는 많지만, 어디에 써야 할지를 아는 것이 진짜 실력입니다.
'홍정모 따라 배우는 C++ > C++ 함수' 카테고리의 다른 글
| 함수의 인자전달 방법 1. 값에 의한 전달(Call by value) (0) | 2025.06.10 |
|---|---|
| 매개변수(parameter)와 인자(argument)의 차이 완벽 정리(C++) (0) | 2025.06.10 |
- Total
- Today
- Yesterday
- c언어
- 파이썬
- 파이썬코딩
- 프로그래머스
- 알고리즘 문제풀이
- python 알고리즘
- 문제풀이
- 동적 계획법
- 프로그래밍
- 브루트포스
- 그리디
- 알고리즘문제풀이
- 문제 풀이
- 문자열처리
- 알고리즘
- 동적계획법
- 알고리즘기초
- 객체지향
- 상속
- 코딩
- 백준
- 코딩테스트
- dfs
- Python
- 코딩 테스트
- HTML
- DP
- 그래프 탐색
- 그리디알고리즘
- C++
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
