본문 바로가기
Embedded System/소프트웨어 (C,C++)

[C++] 참조자 (Reference)/ 참조에 의한 호출(Call-by-reference)

by MachineJW 2024. 6. 21.

1. C++ 참조자

#include <iostream>
using namespace std;

int main(void) {
	int num1 = 2024;
	int &num2 = num1; // num2는 변수 num1을 참조한다. (num1의 참조자가 된다.) 
	
	num2++;
	
	cout<<"NUM1: "<<num1<<endl;
	cout<<"NUM2(REF): "<<num2<<endl;
	cout<<"NUM1_MEMORY: "<<&num1<<endl;
	cout<<"NUM2(REF)_MEMORY: "<<&num2<<endl; // num1 과 같은 메모리를 사용한다. 
	return 0;
}

 

기존 C언어에서 & 연산자는 변수의 주소값을 반환하는 연산자 였다.

변수선언에서 변수명 앞의 & 연산자는 여기서 "참조자(Reference)" 선언의 의미가 된다.

  • 참조자는 비유적으로 별칭이다. (변수로 봐도 문제가 없다)
  • 오로지 변수만 참조할 수 있다.
  • 참조하는 변수 메모리 공간을 사용한다.
  • 참조자의 수에는 제한이 없으며, 참조자를 대상으로도 참조자를 선언할 수 있다. (하지만, 필요이상으로 선언하는 것은 바람직하지 못하다.)
  • 아래는 참조자 선언의 잘못된 예시이다.
int &ref = 20; // 잘못됨, 참조자는 변수만 선언할 수있다.
int &ref; // 잘못됨, 참조자는 선언과 동시에 변수를 참조해야한다.
int &ref = NULL; // 잘못됨, 선언하면서 NULL로 초기화하는 것도 불가능하다.

 

2. Call by reference (함수 호출 이야기)

int Adder (int n1, int n2){
	return n1+n2;
} // call by vale


int SwapByRef(int* ptr1, int* ptr2){
	int temp = *ptr1;
	*ptr1 = *ptr2; 
	*ptr2 = temp;
} // call by reference

// 호출 예시
int main(void) {
	int num1 = 1;
	int num2 = 2;
	
	SwapByRef(&num1, &num2); 
}
  • C++에서 Call by reference 개념은 참조자를 활용할 수 있다. (물론 포인터 변수도 가능하지만)
  • C언어에서는 주소 값을 이용한 Call by reference (C언어 한정으로 Call by Adderess라고도 한다. 그러나 Call by Reference 개념과 동일하게 여긴다.) 만 활용할 수 있었다.
int SwapByRef(int &ref1, int &ref2){
	int temp = ref1;
	ref1 = ref2; 
	ref2 = temp;
} // call by reference (C++ 참조자를 활용)

int main(void) {
	int num1 = 1;
	int num2 = 2;	
	SwapByRef(num1, num2); // 호출 시에 주소값(&)을 넣어줄 필요가 없다! 
}
  • 포인터는 잘못 사용할 확률이 상대적으로 더 높은반면, 참조자의 활용은 더 쉽다.
  • C언어에서는 함수의 호출문장만 보고도 값이 변경되지 않음을 알 수 있지만, C++의 참조자 활용은 이것이 불가능하다. 최소한 함수의 원형을 파악해야한다. (즉, 코드의 가독성이 좋지 못하다.)
  • 함수 내에서, 참조자를 통한 값의 변경을 진행하지 않을 경우 ,참조자를 const로 선언해서 함수의 원형만 봐도 값의 변경이 이뤄지지 않음을 알수 있게 해야한다.
void myFunc(const int &ref) {.....
} // 함수 myFunc 내에서 참조자 ref를 이용한 값의 변경은 하지 않겠다.
  • 참조자의 단점 때문에 참조자를 사용하지 않는 C++ 프로그래머의 수도 적지 않다. 포인터를 사용하는 것이 코드를 더 명확히 작성하는 방법이 된다고 생각하기 때문이다. (답정 포인터...)
  • C++ 기반의 Arduino 라이브러리 구현부 cpp 파일을 확인 중이나 아직 참조자를 활용한 함수구현은 보지 못했다...