C++는 포인터를 다루기 위해 두 가지 연산자를 제공합니다. 하나는 변수의 메모리 주소를 구하는 주소 연산자(&)이고, 다른 하나는 주소에 저장된 값을 꺼내오는 간접 참조(역참조) 연산자(*)입니다.
포인터(pointer)란 다른 변수의 메모리 주소를 값으로 저장하는 변수를 말합니다. 어떤 변수가 다른 변수의 주소를 담고 있을 때, 그 변수가 다른 변수를 "가리킨다(point to)"고 표현합니다. 포인터가 가리키는 대상은 int나 char 같은 기본 자료형은 물론, 객체, 구조체, 심지어 또 다른 포인터까지 가능합니다.
간접 참조 연산자(*)는 주소 연산자(&)와 정확히 반대되는 역할을 하는 단항(unary) 연산자입니다. 피연산자로 지정된 주소에 저장되어 있는 값을 반환하며, 이를 흔히 '역참조(dereference)'라고 부릅니다.
& 연산자와 * 연산자의 관계
두 연산자는 서로 상보적인(complementary) 관계입니다. & 연산자는 변수에서 출발해 그 변수의 주소를 얻어내고, * 연산자는 주소에서 출발해 그 주소에 저장된 값을 얻어냅니다. 즉, 한쪽은 '값 → 주소' 방향으로, 다른 쪽은 '주소 → 값' 방향으로 동작합니다.
예제 코드
#include <iostream>
using namespace std;
int main () {
int var;
int *ptr;
int val;
var = 3000;
// var의 주소를 가져와 ptr에 저장
ptr = &var;
// ptr이 가리키는 주소에 있는 값을 가져옴
val = *ptr;
cout << "Value of var :" << var << endl;
cout << "Value of ptr :" << ptr << endl;
cout << "Value of val :" << val << endl;
return 0;
}실행 결과
위 코드를 컴파일하여 실행하면 다음과 같은 결과가 출력됩니다.
Value of var : 3000 Value of ptr : 0xbff64494 Value of val : 3000
결과 해석
출력 결과를 보면 세 변수의 관계를 명확히 알 수 있습니다. ptr에는 var의 메모리 주소(0xbff64494)가 저장되어 있고, *ptr을 통해 그 주소에 담긴 값인 3000을 읽어와 val에 대입했습니다. 결국 val은 var와 같은 값 3000을 갖게 되며, 이것이 포인터와 역참조 연산자의 기본 동작 원리입니다.