C++를 공부하다 보면 자연스럽게 등장하는 개념 중 하나가 참조(Reference)와 포인터(Pointer)이다. 둘 다 특정 메모리를 가리키는 역할을 하지만, 동작 방식이나 사용 목적에서 많은 차이가 있다.
참조는 다른 변수의 별명(Alias)이다. 참조를 통해 원래 변수를 간접적으로 접근하거나 수정할 수 있다. 선언 후에는 참조가 가리키는 대상을 변경할 수 없다.
int x = 42;
int& ref = x; // ref는 x의 참조
cout << x << endl; // 출력: 42
cout << ref << endl; // 출력: 42
ref = 100; // ref를 통해 x의 값을 변경
cout << x << endl; // 출력: 100
ref는 변수 x의 별명으로 동작한다. 따라서 ref를 통해 x의 값을 수정할 수 있다.포인터는 메모리 주소를 저장하는 변수이다. 특정 메모리 주소를 통해 데이터를 간접적으로 접근하거나 조작할 수 있다.
int x = 42;
int* ptr = &x; // ptr은 x의 주소를 저장
cout << x << endl; // 출력: 42
cout << *ptr << endl; // 출력: 42
*ptr = 100; // ptr이 가리키는 주소의 값을 변경
cout << x << endl; // 출력: 100
ptr은 변수 x의 주소를 저장하고, ptr을 통해 x에 접근하거나 값을 변경할 수 있다.| 특징 | 참조(Reference) | 포인터(Pointer) |
|---|---|---|
| 주소 저장 | 별도의 주소를 저장하지 않으며, 다른 변수의 별명임. | 메모리 주소를 저장하고, 주소를 통해 데이터에 접근함. |
| NULL 가능성 | NULL 참조 불가능. 항상 유효한 변수를 가리켜야 함. | NULL을 가질 수 있음. 신중히 사용해야 함. |
| 초기화 | 선언 시 반드시 초기화 필요. | 초기화 없이 선언 가능. |
| 가리키는 대상 변경 | 가리키는 대상을 변경할 수 없음. | 포인터가 다른 메모리를 가리키도록 변경 가능. |
| 사용 복잡도 | 간단하고 안전함. | 더 유연하지만, 주소 조작으로 인해 위험성이 있음. |
void updateValue(int& ref) {
ref += 10; // 원본 값을 수정
}
int main() {
int x = 42;
updateValue(x);
cout << x << endl; // 출력: 52
return 0;
}
void updateValue(int* ptr) {
*ptr += 10; // 포인터가 가리키는 주소의 값을 수정
}
int main() {
int x = 42;
updateValue(&x);
cout << x << endl; // 출력: 52
return 0;
}
참조와 포인터는 각각의 장단점이 있으며, 적절한 상황에서 선택적으로 사용하는 것이 중요하다. 참조는 간단하고 안전하지만 유연성이 떨어지며, 포인터는 더 많은 유연성을 제공하지만 위험성을 동반한다.