0. 포인터의 필요성
(1) 변수
int number = 1;
- 4바이트 정수 타입의 number 변수
- 스택 메모리에 할당됨
- 스택 메모리의 특정 주소(number에 해당하는 주소)에 우리가 원하는 값인 1을 대입
- 즉 특정 메모리에 number라는 이름을 붙인 것과 같다
* 단점
- 전역 변수가 아닌 지역 변수는 외부에서 접근할 수 없음
=> 따라서 포인터를 사용하여 이를 해결할 수 있음
1. 포인터
(1) 정의
//TYPE* 변수이름;
int* ptr;
메모리의 주소를 저장하는 역할을 한다.
ex) 변수 선언 시 '*'가 붙어있다 -> 포인터이다 -> 주소 값을 갖고 있다
int number = 1;
int main()
{
int* ptr = &number; // &number는 number의 주소
return 0;
}
위와 같은 코드로 ptr에 number의 주소를 저장한다.
이때 포인터는 4바이트(32비트) 혹은 8바이트(64비트)로 (시스템에 따라) 고정됨.
(2) 사용
포인터가 가리키는 주소로 가서 값을 수정할 수 있다.
*변수이름 = 값;
int main()
{
int* ptr = &number;
int value1 = *ptr; // value1에 ptr에 저장된 주소의 값을 저장함
*ptr = 2; // ptr에 저장된 주소의 값에 2를 대입함
return 0;
}
즉 '*ptr'은 해당 주소의 값을 뜻한다.
(3) TYPE을 붙이는 이유?
int* ptr = &number;
포인터는 항상 8바이트 혹은 16바이트인데,
위의 코드에서 int와 같이 타입을 붙이는 이유가 뭘까?
=> 해당 주소의 값이 어떤 형식인지 알아야 몇 바이트 까지가 그 주소의 값인지 알 수 있기 때문!!
(4) TYPE의 불일치
int main()
{
__int64* ptr2 = (__int64*)&number;
*ptr2 = 0xAABBCCDDEEFF;
return 0;
}
number는 4바이트 정수가 저장되어 있다. 그런데 ptr2를 강제로 8바이트 정수로 지정하고 주소를 저장하고 값을 변경해 주면
다른 메모리의 영역을 침범해서 값을 덮어씌워 버릴 수 있다.
(5) 활용
광역 변수와 지역 변수의 이름이 동일하면 함수 내에서 사용 시 광역변수의 값을 우선적으로 사용한다.
void SetHp(int hp)
{
hp = 100;
}
int main()
{
int hp = 1;
SetHp(hp); // SetHp(100);
return 0;
}
이 문제를 해결하기 위해 포인터를 사용할 수 있다.
void SetHp(int* hp)
{
*hp = 100;
}
int main()
{
int hp = 1;
SetHp(&hp); //매개변수(주소)
return 0;
}
즉 지역 변수 hp의 값을 100으로 수정할 수 있다.
'기초 C++ 스터디' 카테고리의 다른 글
4-4. 참조 (0) | 2023.05.11 |
---|---|
4-2. 포인터 연산 (0) | 2023.05.11 |
3-7. 구조체 (0) | 2023.05.10 |
3-5. 함수 오버로드, 기본 인자값, 스택 오버플로우 (0) | 2023.05.09 |
3-4. 호출 스택 (0) | 2023.05.09 |