이 포스트에서는 C++에서 참조를 사용하여 값을 전달하는 방법에 대해 설명합니다. 참조를 통해 함수 내에서 원본 데이터를 수정하고 효율성을 높이는 다양한 예제를 살펴보겠습니다.
void swap0(int& px, int& py)
{
int temp = px;
px = py;
py = temp;
}
설명:
swap0
함수는 두 정수를 참조로 받아 값을 교환합니다.px
와 py
는 x
와 y
의 별칭이므로, 함수 내에서 px
와 py
를 변경하면 x
와 y
의 값이 변경됩니다.int main()
{
{
int x = 10, y = 20;
swap0(x, y);
cout << x << endl; // 20
cout << y << endl; // 10
}
{
int x = 10, y = 20;
// swap0(x, y); 풀어쓰기
int& px = x;
int& py = y;
int temp = px;
px = py;
py = temp;
cout << x << endl; // 20
cout << y << endl; // 10
}
}
설명:
swap0
함수를 호출하여 x
와 y
의 값을 교환합니다.swap0
함수의 동작을 수동으로 수행합니다. px
와 py
는 x
와 y
의 참조입니다. 이를 통해 값을 교환합니다.struct Weapon
{
int price;
int power;
};
void upgrade(Weapon& weapon)
{
weapon.power += 10;
weapon.price += 10;
}
void print(const Weapon& weapon)
{
cout << weapon.power << endl;
cout << weapon.price << endl;
}
설명:
Weapon
구조체는 price
와 power
필드를 가집니다.upgrade
함수는 Weapon
참조를 받아 power
와 price
를 수정합니다.print
함수는 Weapon
의 const 참조를 받아 값을 출력합니다. const 참조는 함수 내에서 값을 변경할 수 없음을 보장합니다.int main()
{
{
Weapon weapon{10, 20};
upgrade(weapon);
print(weapon); // 30 20
}
}
설명:
upgrade
함수를 호출하여 weapon
의 power
와 price
를 증가시킵니다.print
함수를 호출하여 수정된 weapon
의 값을 출력합니다.int main()
{
{
int num;
cin >> num; // num을 레퍼런스로 넘겨주기 때문에 scanf처럼 num의 주소로 넘겨주지 않아도 된다
}
}
설명:
cin
은 num
을 참조로 받아 사용자로부터 입력받은 값을 설정합니다. 참조를 사용하므로 주소를 명시적으로 전달할 필요가 없습니다.int main()
{
{
int nums[] = {1, 2, 3, 4};
for (int num : nums)
{
num = 0; // nums의 값이 안 바뀐다
}
for (int& num : nums)
{
num = 0; // nums의 값이 바뀐다
}
for (const int& num : nums)
{
// num = 0; // nums의 값을 바꿀 수 없다. 레퍼런스로 넘겼기 때문에 성능에 유리하다
}
}
}
설명:
num
이 값으로 전달되므로 nums
배열의 값이 변경되지 않습니다.num
이 참조로 전달되므로 nums
배열의 값이 0으로 변경됩니다.num
이 const 참조로 전달되므로 값을 변경할 수 없습니다. 이는 성능상 이점을 제공합니다.int squarev(int value)
{
return value * value;
}
int squaref(const int& ref)
{
return ref * ref;
}
int main()
{
{
int x = 10;
cout << squarev(10.1) << endl;
// 상수 참조는 호환이 되는 타입은 임시 객체를 생성해서 가리키게 한다.
// 이 경우 10.1은 double 형이고 squaref의 ref는 const int& 이기 때문에
// 10 임시 객체가 만들어진다.
// 상수 참조 타입은 최대한 일반 값 타입과 호환이 되도록 하고 싶은 의도
cout << squaref(10.1) << endl;
}
}
설명:
squarev
함수는 정수를 값으로 받아 제곱을 반환합니다.squaref
함수는 정수를 const 참조로 받아 제곱을 반환합니다.squarev
호출 시 10.1
은 int
로 변환되어 100
을 반환합니다.squaref
호출 시 10.1
은 double
타입이지만, const 참조는 호환되는 타입을 임시 객체로 생성하여 가리키므로 10
임시 객체가 생성되어 제곱된 값을 반환합니다.int& func0()
{
int num = 0;
return num; // 위험하다. num은 삭제 됨
}
int& func1(Weapon& weapon)
{
return weapon.power;
}
int main()
{
{
Weapon weapon{10, 20};
func1(weapon) = 30; // 이런 것도 된다
}
}
설명:
func0
함수는 지역 변수 num
의 참조를 반환합니다. 이는 위험합니다. 함수가 종료되면 num
은 삭제되므로 참조가 유효하지 않습니다.func1
함수는 Weapon
구조체의 power
필드의 참조를 반환합니다. 이를 통해 main
함수에서 power
를 직접 수정할 수 있습니다.C++에서 참조를 사용하면 함수 내에서 원본 데이터를 효율적으로 수정할 수 있습니다. 참조를 사용하면 포인터처럼 주소를 명시적으로 전달하지 않아도 되며, 코드가 간결해지고 가독성이 높아집니다. const 참조를 사용하면 값의 수정이 불가능하도록 하여 안전성을 높일 수 있습니다. 이러한 참조 전달 방식을 이해하는 것은 C++ 프로그래밍에서 매우 중요합니다.