<aside> <img src="/icons/list_gray.svg" alt="/icons/list_gray.svg" width="40px" />
목차
</aside>
내가 사용한 파이썬에서는 생소한 개념인 포인터는 로우 레벨에서 변수와 메모리 주소를 직접 가리켜 값을 읽거나 수정하는 개념이다.
int main()
{
int number = 1;
int* ptr = &number;
return 0;
}
위 코드에서 number는 일반 변수이고, ptr은 number의 메모리 주소를 가리키는 포인터 변수이다. &(주소 연산자)를 통해 number의 메모리 주소를 ptr에 할당했다.
실행시켜서 실제로 이 변수들이 메모리에서 어떻게 저장되어 있는지 확인해보자.
메모리에서 확인해보기
<aside> 💡
메모리 확인법
Rider에서는 디버그 실행 후, 디버그 탭에서 메모리를 확인할 수 있다.

주의해야할 점으로, Rider에서는 byte 단위에서는 역순으로 읽어야 한다.

주소 연산자(&)
먼저, &number를 메모리에 검색하여, number의 값이 메모리에 할당되어 있는지 확인한다.

그럼 이제 &ptr을 메모리에 검색하여 어떻게 할당되어 있는지 확인한다.

Rider에서의 메모리 읽기 역순에 유의!
실제로 그러한지 증명하기 위해서, 메모리 검색창에 **&(주소 연산자)**을 제외한 ptr를 통해 검색해본다.

이미 변수에서 데이터 타입을 선언했는데도, 포인터에 타입 선언이 필요한 이유에 대해서 궁금했다.
강의와 검색을 통해서 찾아본 결과, 포인터의 타입 선언은 메모리를 참조할 때 데이터의 크기와 해석 방식을 명확히 하게 해준다.
타입 불일치 문제
int main()
{
int number = 1;
int* ptr = &number;
__int64* ptr2 = (__int64*)&number;
*ptr2 = 0xAABBCCDDEEFF;
return 0;
}
포인터의 데이터 타입을 변수와 다르게 선언하기 위해, 변수를 강제로 타입을 캐스팅하여 선언할 때, 다음과 같은 일이 발생할 수 있다.
위와 코드와 같이 타입을 캐스팅한 후, *ptr2에 0xAABBCCDDEEFF와 같이 관찰하기 쉬운 값을 대입하였다.

이를 통해서, 포인터 타입 선언은 변수와의 통일된 타입임을 표시하여 잘못된 접근과 변환을 방지할 수 있다.
그러면 실제로 포인터를 통해서 어떻게 함수 간 매개변수를 전달할까? 아래 코드를 통해서, 매개변수를 전달하는 과정을 확인해보자.
void UpgradeHP(int* ptr)
{
*ptr = 2000;
}
int main()
{
int hp = 100;
UpgradeHP(&hp);
}
위 코드를 실행하여 메모리를 확인해보면, 다음과 같은 과정으로 포인터를 통해 매개변수가 전달된다.

과정 & 풀이
먼저, main 함수에서 hp 변수가 생성되어, 100 초기 값이 메모리에 할당된다.

16진수에서 0x64 = 100이다.
UpgradeHP 함수가 호출될 때, hp 변수의 메모리 주소가 매개변수로 전달된다.
UpgradeHP 함수 내부에서는 전달받은 포인터(ptr)를 통해 hp 변수의 메모리 주소에 직접 접근한다.
포인터를 통해 hp 변수의 값을 2000으로 변경하면, main 함수의 원본 hp 변수의 값도 함께 변경된다.

위 예시를 통해 포인터를 사용하면 함수 내에서 원본 변수의 값을 직접 수정할 수 있다는 것을 확인했다.
포인터 연산은 C++에서 변수의 주소를 가리키고 조작하는 기능들을 의미한다.
각각의 연산자들은 다음과 같은 특징을 가진다.
주소 연산자(&)
int number = 1;
int* ptr = &number;
**주소 연산자(&)**는 변수의 메모리 주소를 가져오는 연산자이다.
산술 연산자(+,-)
int* int_ptr = 0;
char* char_ptr = 0;
double* double_ptr = 0;
int_ptr += 1; // 4바이트 증가
char_ptr += 1; // 1바이트 증가
double_ptr += 1; // 8바이트 증가
int_ptr -= 1; // 4바이트 감소
char_ptr -= 1; // 1바이트 감소
double_ptr -= 1; // 8바이트 감소
**산술 연산자(+,-)**는 포인터에 대해 덧셈과 뺄셈 연산을 수행할 수 있다.
이때 증감되는 값은 포인터가 가리키는 데이터 타입의 크기에 따라 달라진다.
// 다음 메모리 주소
++ptr;
// 이전 메모리 주소
--ptr;
마찬가지로, **증가 연산자(++)**를 사용하면 포인터가 가리키는 주소를 데이터 타입의 크기만큼 증가시키고, **감소 연산자(--)**를 사용하면 그만큼 감소시킨다.