C++ 참조(Reference)란?
변수를 참조(reference)로 선언하면 해당 변수는 기존 변수의 또 다른 이름, 즉 별칭(alias)이 됩니다. 참조는 새로운 메모리 공간을 만드는 것이 아니라 이미 존재하는 변수를 그대로 가리키며, 참조를 통해 값을 읽거나 수정하면 원본 변수에 그대로 반영됩니다.
문법
Type &newname = existing_name;
선언 및 초기화 예제
int num = 10;
int &ref = num; // ref는 num의 별칭
참조는 선언과 동시에 반드시 초기화해야 하며, 한 번 특정 변수에 연결되면 다른 변수를 가리키도록 변경할 수 없습니다.
C++ 포인터(Pointer)란?
포인터(pointer)는 변수의 메모리 주소를 저장하는 변수입니다. 포인터를 역참조(dereference, *)하면 해당 주소에 저장된 값에 간접적으로 접근할 수 있습니다.
문법
Type *pointer;
선언 및 초기화 예제
int num = 10;
int *ptr = # // ptr은 num의 주소를 저장
포인터는 선언만 해두고 나중에 초기화할 수도 있으며, 아무것도 가리키지 않는 상태(null)로 둘 수도 있습니다.
참조와 포인터의 주요 차이점
- 역할: 참조는 기존 변수를 다른 이름으로 가리키는 데 사용되고, 포인터는 변수의 메모리 주소를 저장하는 데 사용됩니다.
- null 값: 참조에는 null 값을 할당할 수 없지만, 포인터에는 nullptr을 할당할 수 있습니다.
- 접근 방식: 참조는 일반 변수처럼 값에 직접 접근하는 방식으로 사용되는 반면, 포인터는 역참조(*)를 통해 간접적으로 값에 접근합니다.
- 초기화: 참조는 선언 시 반드시 초기화해야 하지만, 포인터는 초기화가 필수가 아닙니다.
- 메모리: 참조는 원본 변수와 같은 메모리 주소를 공유하며 컴파일러에 따라 스택에 약간의 공간을 차지할 수 있지만, 포인터는 스택에서 자신만의 고유한 메모리 주소와 크기(일반적으로 4~8바이트)를 가집니다.
- 재할당: 참조는 한 번 연결되면 다른 대상을 가리킬 수 없지만, 포인터는 언제든 다른 변수의 주소를 가리키도록 변경할 수 있습니다.
- 포인터 산술: 포인터는 증감 연산 등 포인터 산술이 가능하지만, 참조에는 이러한 연산을 적용할 수 없습니다.
참조 vs 포인터 비교표
| 구분 | 참조(Reference) | 포인터(Pointer) |
|---|---|---|
| 초기화 | 선언 시 필수 | 선택 사항 |
| null 가능 여부 | 불가능 | 가능(nullptr) |
| 재할당 | 불가능 | 가능 |
| 메모리 주소 | 원본 변수와 공유 | 자체 주소 보유 |
| 값 접근 | 직접 접근 | * 연산자로 간접 접근 |
결론적으로, 유효한 객체를 항상 가리켜야 하고 단순한 별칭이 필요한 경우에는 참조가 더 안전하고 간결하며, 대상을 유동적으로 바꾸거나 null 상태가 필요한 경우에는 포인터가 적합합니다.