-
C++ 포인터와 레퍼런스C++/Common 2023. 10. 3. 20:56
6일간의 연휴간 C++을 익히는 시간을 가졌습니다.
10년전에 처음 프로그래밍을 배울때 가장 어려웠던 C의 포인터 개념을 다시 한번 되새기고 남기려고 이 포스팅을 남깁니다.void 포인터
- 타입과 상관없이 포인터를 생성합니다. nullptr은 비어있는 포인터 변수를 만들때 넣습니다.
void* pointer = nullptr;
포인터 할당
int value = 100; int* ptrValue1 = &value;
포인터는 다른 변수의 주소값을 할당해서 지정합니다.
int value = 100; int* ptrValue1 = &value; int* ptrValue2 = ptrValue1;
혹은 다른 포인터를 그대로 지정하여 사용할 수 있습니다.
여기서 &value 와 같이 변수앞에 &이 붙는 경우는 변수의 주소라고 생각하면 편합니다.
int* ptrValue2 = ptrValue1은 ptrValue1을 다른 기호없이 사용할 경우 그냥 주소값을 넘겨주는 개념으로 볼수 있습니다.포인터의 사용
cout << *ptrValue1 << endl;
{*포인터변수}명 으로 사용하게되면 포인터가 가르키고 있는 값을 그대로 사용합니다.
이미 할당된 포인터에 다른값을 넣을때에도 마찬가지 입니다.*ptrValue1 = 20;
이런식으로 할당합니다.
포인터에서 ++를 하게 되면?
int a[5] = { 1,2,3,4,5 }; int* ptrA = &a[0]; ptrA++; cout << *ptrA << endl;
ptrA는 처음에 a배열의 첫번째 인덱스에 해당하는 값을 가르키고 있습니다.
그러다 ptrA++; 를 하게되어 다음 인덱스를 가르키는 것을 볼수 있습니다.int의 크기는 4바이트이고
ptrA++를 하게되면 4바이트만큼 이동하여 보여주는 것을 알 수 있습니다.따라서 C++에서 함수에서 배열을 전달 하는것보다는
다음과 같이 포인터와 length를 전달하는 경우가 많습니다.void FunctionName(int* ptr, int length)
함수에서 사용
void Swap(int* a, int*b) { int temp = *a; *a = *b; *b = temp; }
이런 Swap 함수가 있다고 할때 포인터 변수를 넘길땐
Swap(ptrValue1, ptrValue2);
이렇게 그냥 변수명을 넘겨줍니다.
Swap 메서드의 매개변수를 풀어쓰면int* a = ptrValue1;
int* b = ptrValue2;
이런식으로 생각하면 좀 더 생각하기가 편합니다.함수에서 사용시 주의사항
int* ExceptionCase(int a) { int* aPtr = &a; return aPtr; }
함수스코프내에서 선언된 변수의 수명을 생각해야합니다.
스택메모리가 Pop되면서 해당스택은 사용할수 없게 되는데
사용불가된 스택에서 선언된 포인터변수를 사용하도록 설정하고 있는 내용입니다.이중포인터
int value = 100; int* ptrValue1 = &value; int** ptrValue2 = &ptrValue1; cout << *ptrValue1 << endl; cout << **ptrValue2 << endl;
포인터를 가르키는 포인터를 만들게 되면 그게 이중포인터입니다.
{**변수명}으로 사용하게되면 원본포인터가 가르키는 값을 그대로 사용합니다.포인터의 멤버 사용
class Player { public: virtual void Move() { cout << "Player Move()" << endl;} void Dance() { this->Move(); } }; void MovePlayer(Player* p) { p->Move(); } int main() { Player player; MovePlayer(&player); player.Dance(); }
포인터의 멤버를 사용할때에는 -> 연산자를 사용합니다.
자기자신의 인스턴스를 사용할때도 this. 이 아니라 this->를 사용합니다.Reference (참조)
void Swap(int& a, int& b) { int temp = a; a = b; b = temp; } int main() { int a = 0; int b = 1; Swap(a, b); int& c = a; cout << a << endl; cout << b << endl; cout << c << endl; }
포인터를 사용하지 않고 기본변수의 참조를 전달하는 방식입니다.
int& c와 같은 레퍼런스는 a의 별명으로 사용되었다고 생각하면 더 편합니다.포인터는 스택에 64비트 환경에서 새로운 공간을 할당하지만 레퍼런스는 기존의 주소를 전달하는 방식으로 사용됩니다.
대신 레퍼런스는 한번 지정한뒤에는 다른 변수의 참조로 바꾼다던가 할수 없습니다.포인터는 다른 변수의주소를 재할당하거나 혹은 메모리단위로 이동하여 사용하거나 할수 있기때문에 용도에 따라 사용하면 됩니다.
'C++ > Common' 카테고리의 다른 글
생성자 초기화, explicit (1) 2023.10.05