nullptr 가능)->, *)을 사용하여 접근nullptr 체크가 필요 (주소가 없는 경우 고려). 연산자 사용)➡ 참조는 포인터와 기능적으로 같지만, 문법적으로 더 간단하고 안전함
StatInfo 구조체 정의#include <iostream>
using namespace std;
// 구조체 정의
struct StatInfo {
int hp; // 체력 (4바이트)
int attack; // 공격력 (4바이트)
int defence; // 방어력 (4바이트)
};
StatInfo 구조체는 체력(hp), 공격력(attack), 방어력(defence)을 저장하는 구조체입니다.📍 메모리 구조 예시 (32비트 시스템)
| 주소 | 변수명 | 크기 |
|----|-----|----|
| 0x1000 | hp | 4바이트 |
| 0x1004 | attack | 4바이트 |
| 0x1008 | defence | 4바이트 |
void CreateMonster(StatInfo* info) {
info->hp = 100;
info->attack = 8;
info->defence = 5;
}
✅ 포인터(StatInfo* info)를 사용하여 원본을 직접 수정
✅ 메모리 복사 없이 원본 데이터 접근 가능
📍 함수 호출 예시
StatInfo monster;
CreateMonster(&monster);
| 전달 방식 | 설명 |
|---|---|
&monster | monster의 주소를 전달 (포인터 사용) |
info->hp = 100; | monster.hp를 직접 수정 |
➡ 포인터(->)를 사용하여 구조체 멤버에 접근 가능
void PrintInfoByPtr(const StatInfo* const info) {
if (info == nullptr) {
return;
}
cout << "-------------------- " << endl;
cout << "HP: " << info->hp << endl;
cout << "ATT: " << info->attack << endl;
cout << "DEF: " << info->defence << endl;
cout << "-------------------- " << endl;
}
✅ 포인터(StatInfo* info)를 사용하여 원본 데이터를 직접 출력
✅ 메모리 복사 없이 원본 값 사용 가능
✅ 포인터가 nullptr인 경우를 체크하는 코드 포함
📍 함수 호출 예시
PrintInfoByPtr(&monster);
| 전달 방식 | 설명 |
|---|---|
&monster | 원본 주소 전달 |
info->hp | 원본 데이터를 직접 출력 |
➡ 포인터(->)를 사용하여 구조체 멤버 접근
void PrintInfoByRef(const StatInfo& info) {
cout << "-------------------- " << endl;
cout << "HP: " << info.hp << endl;
cout << "ATT: " << info.attack << endl;
cout << "DEF: " << info.defence << endl;
cout << "-------------------- " << endl;
}
✅ 값 전달처럼 보이지만, 내부적으로 주소 전달과 동일한 방식
✅ 포인터(* / ->) 없이 일반 변수처럼 사용 가능
✅ 메모리 복사 없이 원본 데이터 직접 접근
📍 함수 호출 예시
PrintInfoByRef(monster);
| 전달 방식 | 설명 |
|---|---|
monster | 원본 주소를 기반으로 전달 |
info.hp | 원본 데이터를 직접 출력 |
➡ 포인터보다 가독성이 좋고, 값 전달 방식보다 성능이 뛰어남
StatInfo* FindMonster() {
// TODO : Heap 영역에서 몬스터를 찾는 로직
return nullptr;
}
✅ 몬스터를 찾으면 해당 몬스터의 주소를 반환하고, 찾지 못하면 nullptr을 반환
✅ 포인터를 사용하면 존재하지 않는 데이터(nullptr)를 표현할 수 있음
📍 함수 호출 예시
StatInfo* foundMonster = FindMonster();
if (foundMonster) {
PrintInfoByPtr(foundMonster);
}
#define OUT
void ChangeInfo(OUT StatInfo& info) {
info.hp = 1000;
}
✅ 참조를 사용하여 StatInfo 구조체의 값을 직접 수정 가능
✅ OUT 매크로를 사용하여 함수의 출력 파라미터임을 명시
📍 함수 호출 예시
ChangeInfo(monster);
PrintInfoByRef(monster);
main() 함수int main() {
StatInfo info;
CreateMonster(&info);
// 포인터 vs 참조 세기의 대결
// 성능 : 똑같음!
// 편의성 : 참조 승!
StatInfo* pointer = nullptr;
pointer = &info;
PrintInfoByPtr(pointer);
StatInfo& reference = info;
PrintInfoByRef(reference);
ChangeInfo(OUT info);
// 보너스) 포인터로 사용하던걸 참조로 넘겨주려면?
PrintInfoByRef(*pointer);
// 보너스) 참조로 사용하던걸 포인터로 넘겨주려면?
PrintInfoByPtr(&reference);
return 0;
}
✅ 포인터(*pointer)와 참조(&reference)의 사용 차이를 비교
✅ 포인터(*pointer)에서 참조(&)로 변환하는 예제
✅ 참조(&reference)에서 포인터(*)로 변환하는 예제
| 비교 항목 | 포인터 | 참조 |
|---|---|---|
| 메모리 주소 저장 | ✅ 가능 | ❌ 불가능 |
nullptr 가능 여부 | ✅ 가능 | ❌ 불가능 |
| 초기화 필요 여부 | ❌ 선택적 | ✅ 필수 |
| 사용 연산자 | ->, * | . |
| 사용 예시 | StatInfo* ptr = &info; | StatInfo& ref = info; |
✅ 일반적으로 참조(&)가 편리하지만, 포인터(*)는 nullptr을 활용할 수 있는 장점이 있음
✅ 바뀌지 않는 데이터는 const &로 참조 전달하는 것이 일반적