포인터, 다중포인터
TYPE* 변수이름;
일단 두가지 요소
- TYPE
- *
변수를 선언할 때 *이 등장했다 ->포인터 = 주소
Ex) int* ptr = &number;
포인터라는 바구니는 4바이트(32비트) or 8바이트(64비트) 고정크기
근데 남의 주소를 갖고 뭘 하라는거지?
추가 문법 : [주소를 저장하는 바구니가] 가리키는 주소로 가서 무엇인가를 해라!
*변수이름 = 값;
ex) int value = *ptr / *ptr = 2; value값은 2가됨
변수선언(주소를 저장하는 바구니다!)
사용할때(포탈타고 순간이동)
TYPE은 왜 붙여줄까?
* 은 포인터의 의미 = 주소를저장하는 바구니
주소에 가면 뭐가있는데?
Ex) 결혼식 청첩장에 있는 주소 = 예식장 주소, 명함주소 = 회사주소
** 포인터 연산
1) 주소 연산자(&) - 해당 변수의 주소를 알려주세요, 해당 변수 타입에 따라서 타입*반환
Ex) int* pointer = &number;
2) 산술 연산자(+,-) - 포인터에서 +나-등 산술 연산으로 1을 더하거나 빼면, 정말 그 숫자를 더하고 빼라는 의미가 아니라 한번에 TYPE의 크기만큼 이동하라는 뜻. 다음/이전 바구니로 이동하고싶다 라는 뜻. 1을 더더하면 = 바구니 1개 이동시켜라, 3을 더하면 바구니 3개 이동시켜라
Ex) pointer +=1; 옆 주소로 옴겨라
3) 간접연산자(*) - 포탈을 타고 해당 주소로 ~슝 이동
Ex) number = 3; == *pointer = 3; // 둘이 같은 의미
struct ObjectInfo
{
int attack;
int hp;
}
Player.hp = 100;
Player.attack = 10;
ObjectInfo* playerPtr = &Player;
(*playerPtr).hp = 200;
(*playerPtr).attack = 200;
4) 간접 멤버 연산자(->) - .과*을 합쳤음 ->간접연산자(포탈타고 해당주소로 감)
(*playerPtr).hp = 200; == playerPtr->hp = 200;
*포인터를 사용할 경우 일반적으로 값을 넣을때(중간에 스택로컬에 넣었다가 다시 옴김)와 달리 그 주소값에 막바로 값을 넣어줘서 중간과정이 없어 효율이 더 좋음
결론 : 정보가 변하지 않을때는 그값을 직접적으로 넣어줘도 되지만 변할 경우엔 포인터를 사용하는게 효율적임
- 값 전달 방식 : 복사 후 꺼내씀 / 2) 주소전달 방식 : 주소값을 넘겨받아 사용
*어떠한 주소도 가르키지 않는다고 하려면 int* pointer = nullptr; 하면됨
다중 포인터
const char* msg = "hello";
const char** pp = &msg;
*pp = "Bye";
- 이런식으로 *두개를 붙여 문자열 주소로 가서 내용 수정 가능
- msg를 출력시 Bye 가 뜸
- 양파까기라고 생각하면 쉬움 / *을 하나씩 까면서 타고 간다라고 생각하면됨
- 참조도 작동
const char* msg = "hello";
const char*& pp = msg;
pp = "Si";