포인터(pointer)는 “객체다”: 메모리 공간을 차지하며 자기 자신의 주소와 **저장된 값(=어떤 객체의 주소)**을 가진다.
참조(reference)는 “객체가 아니다”: 다른 객체의 또 다른 이름(alias)일 뿐, 독립 주소가 없다.
연산자 의미
&x: x의 주소(address-of)p: p가 가리키는 대상(dereference)포인터의 값 상태: (1) 유효 객체를 가리킴, (2) 배열의 ‘한 칸 뒤’(end)와 혼동 금지, (3) null(아무것도 가리키지 않음), (4) 미초기화(쓰레기 값) — 절대 사용 금지
안전 수칙: “모든 포인터는 선언과 동시에 초기화”, 사용 전 null 체크, 해제 후 재초기화.
void* 는 “형 모르는 메모리 블록”을 가리키는 범용 포인터 — 산술·역참조 불가, 반드시 적절한 타입으로 캐스팅 후 사용.
이중 포인터(T**): “포인터를 가리키는 포인터”. 동적 할당, 이차원 배열, 함수에서 포인터를 바꾸어 반환할 때 유용.
참조는 포인터를 가리킬 수 없지만(정확히는 “포인터를 가리킨다”가 아니라) **‘포인터에 대한 참조’**는 가능: int*& rp = p; 형태(=“포인터라는 ‘객체’를 다른 이름으로 부르기”).
int* p; → p 자체가 메모리에 존재(예: 주소 0x200).