💋 참조란?
✔️ 정의
참조는 어떤 변수의 다른 이름을 제공합니다.
예를 들어, 변수 robert
에 대한 참조를 만들면, 이 참조를 통해 robert
변수를 직접 조작할 수 있습니다.
int robert = 10;
int& bob = robert; // bob은 robert의 참조
bob = 20; // robert의 값도 20으로 변경됨
bob
은 robert
의 저장 위치에 대한 참조이며, bob
을 통해 robert
를 조작할 수 있습니다. bob
에서 이루어진 변경은 모두 robert
에 반영됩니다.
헷갈리죠?
✔️ 참조 vs 일반변수
만약에 bob이 참조변수가 아니라 일반변수였다 고 생각해 봅시당
int robert = 10;
int bob = robert;
bob = 20;
이렇게 되면 bob은 단지 robert의 10을 복사해갔다가 20으로 변경한 것 뿐, 위의 코드 실행 후에 robert는 10, bob은 20이 되는건데! 참조를 하게 되면 bob에다가 단지 복사가 아니라 실제 변수가 저장된 메모리 주소를 공유하게 됩니다.
참조 변수를 통해 값을 변경하면, 원본 변수의 값도 같이 변경됩니다.
✔️ 이거 왜씀?
C++에서는 C의 포인터를 사용한 call by reference 방식을 더 간단하고 안전하게 만들기 위해서 참조를 사용합니다. 물론 C++에서는 C언어의 대부분을 그대로 사용할 수 있기 때문에 여기서도 포인터를 사용할 수는 있습니다.
하지만 참조를 통해서 포인터를 사용해야 하는 복잡성을 줄여주며, 코드를 더 명확하고 쉽게 만들어 줍니다.
이해가 안된다면 아래의 예시를 보면서 이해를 해보도록 합시당
💋 포인터 vs 참조
함수에 파라미터를 전달할 때 복사가 아닌 원본 변수를 직접 조작하고 싶을 때 포인터 또는 참조를 사용합니다.
여기서는 간단히 사용 방식, 코드상에서의 차이에 대해서만 소개하고 뒤에서 더 자세히 어떤 점이 개선되었는지 설명하겠슴니당
✔️ 포인터를 사용한 Call by Reference
C언어에서는 함수가 변수의 값을 직접 변경하기 위해서 포인터를 사용합니다.
예를 들어, 변수의 값을 함수 내에서 변경하고자 할 때 아래와 같이 call-by-reference를 해야 합니다.
void increment(int *ptr) {
(*ptr)++;
}
int main() {
int num = 10;
increment(&num); // 변수의 주소를 전달
printf("%d", num); // 출력 결과: 11
return 0;
}
여기서 increment
함수는 포인터를 파라미터로 받아 그 포인터가 가리키는 값을 증가시킵니다. 함수를 호출할 때는 변수 num
의 주소를 &num
으로 넘겨줍니다.
✔️ 참조를 이용한 Call by Reference
C++에서는 이러한 패턴을 더 간단하고 안전하게
구현할 수 있는 참조를 사용할 수 있습니다.
참조를 사용하면 포인터와 달리 메모리 주소를 직접 다룰 필요 없이 변수를 직접 참조할 수 있습니다.
void increment(int& num) {
num++;
}
int main() {
int num = 10;
increment(num); // 참조를 이용한 호출
cout << num; // 출력 결과: 11
return 0;
}
여기서 increment
함수는 정수 참조를 매개변수로 받습니다. main
함수에서는 변수 num
을 그냥 전달하면 됩니다. C++의 참조는 포인터처럼 주소를 명시적으로 다루지 않으므로 더 간결하고 안전한 코드 작성이 가능합니다.
💋 반환 타입이 참조일 경우?!!
함수가 변수의 참조를 반환하면, 이 함수의 반환값을 변수처럼 사용할 수 있습니다.
이걸 사용해서 연산자 오버로딩을 더 자연스럽게 구현할 수 있습니다.
double& getMax(double& a, double& b) {
return (a > b) ? a : b;
}
int main() {
double x = 5.0, y = 10.0;
getMax(x, y) = 100.0; // y의 값이 100.0으로 변경됨
return 0;
}
주의사항! 반환되는 참조는 반드시 유효한 메모리 주소를 가리켜야 합니다.
함수 호출이 끝나면 사라져버리는 지역 변수의 참조를 반환하는 것은 위험합니당
항상 유효 범위와 생명 주기를 고려하여 안전하게 참조를 반환해야 합니다.
✔️ 값으로 반환받기 (double result
)
double result = getMax(variable1, variable2);
의 경우
- 함수
getMax
이 참조를 반환하더라도,result
변수에는 원본 변수의 값이 복사 - 이후에
result
의 값을 변경해도 원본variable
에는 아무런 영향이 없습니다. - 원본 데이터의 보호를 위해 사용
✔️ 참조로 반환받기 (double& result
)
double& refResult = getMax(variable1, variable2);
의 경우
refResult
는variable
의 참조로 직접 연결refResult
를 통해 값을 변경하면 원본variable
의 값도 변경- 데이터 복사 없이 원본 데이터를 직접 조작할 필요가 있을 때 사용
💋 참조가 그래서 뭐가 이득?
주로 프로그래밍의 안전성, 간결성을 높이기 위해서!
✔️ 간결성과 직관성
참조는 코드를 더 직관적이고 간결하게 만들어 줍니다. 포인터를 사용할 때는 주소에 접근하고 역참조(*
)를 통해 값을 조작해야 하지만, 참조는 마치 일반 변수처럼 사용할 수 있어 코드가 더 읽기 쉽고 이해하기 쉬워집니다.
✔️ 안전성
참조는 초기화되면 변경할 수 없으며, 반드시 유효한 객체를 가리켜야 합니다. 이는 포인터처럼 NULL이 될 수 있거나, 의도치 않게 변경되는 문제 를 방지합니다. 포인터는 실수로 잘못된 메모리 주소를 참조하거나, 해제된 메모리를 참조하는 등의 실수를 범하기 쉽습니다. 참조는 개발자의 실수 가능성을 줄여 줍니다.
✔️ 함수 오버로딩과 연산자 오버로딩
C++에서 참조는 함수 오버로딩과 연산자 오버로딩에 중요한 역할을 합니다. 참조를 사용함으로써 개발자는 특정 타입의 인자를 받는 여러 버전의 함수를 정의할 수 있으며, 이는 객체 지향 프로그래밍의 다형성을 지원하는 데 기여합니다.
💋 [번외] & 기호는 참조에서도 쓰이고 포인터에서도 쓰이는데,,?
C++에서 &
기호는 컨텍스트에 따라 두 가지 다른 의미로 사용됩니다.
하나는 포인터와 관련된 용도이고, 다른 하나는 참조를 정의하는데 사용됩니다.
둘 다 같은 기호 &
를 사용하지만, 기능적으로는 완전 다릅니다.
✔️ 주소 연산자(Address Operator)로서의 &
포인터와 관련하여 &
는 주소 연산자
로 사용되며, 변수의 메모리 주소를 반환합니다.
예를 들어, 변수 a
의 주소를 얻기 위해 &a
라고 작성할 수 있습니다. 이렇게 얻은 주소는 포인터 변수에 저장될 수 있습니다.
cppCopy code
int a = 5;
int* p = &a; // p는 변수 a의 주소를 저장하는 포인터
✔️ 참조 선언자(Reference Declaration)로서의 &
참조를 선언할 때 &
는 참조 선언자
로 사용됩니다. 이는 변수의 별명을 만드는 데 사용되며, 참조는 선언된 변수의 또 다른 이름으로 사용됩니다.
한 번 참조가 초기화되면, 이 참조는 초기화된 변수와 동일하게 작동하며 변경할 수 없습니다.
cppCopy code
int a = 10;
int& refA = a; // refA는 변수 a의 참조
refA = 20; // a의 값이 20으로 변경됨
도움이 되었다면, 공감/댓글을 달아주면 깃짱에게 큰 힘이 됩니다!🌟
비밀댓글과 메일을 통해 오는 개인적인 질문은 받지 않고 있습니다. 꼭 공개댓글로 남겨주세요!
'C, C++' 카테고리의 다른 글
[C++] static 키워드 제대로 알고 사용하자!: 클래스에서 정적 변수와 정적 함수 사용 방법, 특징, 주의사항 (0) | 2024.05.09 |
---|---|
[C++] const 제대로 알고 사용하자!: 변수, 포인터, 함수, 파라미터에서 각각 사용되는 const의 의미 파헤치기 (0) | 2024.05.08 |
[C++] Inline Functions: 인라인 함수 왜 쓰지? 사용 방법과 장단점 (0) | 2024.05.07 |
[C++] 생성자(Constructor)의 개념, 생성자 정의하고 호출하는 다양한 방법들, 생성자 오버로딩, 기본 생성자 (0) | 2024.04.24 |
[C] C언어의 자료형과 메모리 단위에 대한 기본적인 이해 (0) | 2024.03.14 |