우선 나중에 자세히 설명하겠지만, 일단 보고 넘어가자. 몰라도 된다.
지역 변수는 '스택' 메모리를 사용하고 동적 할당 메모리는 '힙' 메모리를 사용한다.
지금은 몰라도 되지만 시스템을 이용하는데 매우 중요한 부분이니, 꼭 보고 넘어가자.
"큰 메모리가 저장되어 있는 데이터 중에서 일부분을 CPU가 사용하기 위하여 메모리로부터 가져올 때는 메모리 전체를 모두 뒤지면서 찾는 것이 아니라 필요한 데이터가 저장되어 있는 '주소'를 사용하여 직접 접근하여 가져온다."
#include <iostream>
using namespace std;
int main()
{
int x = 5;
cout << x << endl;
cout << &x << endl;
cout << (int)&x << endl;
return 0;
}
output : 5
0135F714
20313876
우리가 변수에 대한 주소를 보고 싶으면 이처럼 &
연산자를 사용하여 출력하면 된다. 하지만 이 주소를 사용하고 싶을 땐, 어떻게 해야 하는가? 이때 포인터를 사용한다.
포인터
: 메모리 주소를 담는 변수
그럼 굳이 왜 포인터를 써야하는 가에 대한 의문(?)이 생길 수도 있다. 예를 들어, 배열의 크기가 겁나게 크다고 생각해보자. 이를 함수 파라미터로 불러오면 배열의 수에 맞게 복사를 해야한다. 이를 몇번이나 반복하면 컴퓨터의 속도가 매우 느려지지 않을까? 이때 배열의 첫 주소와 몇개를 갖고 있는지만 알려준다면, 처리속도면에서 엄청난 성능을 보여주지 않을까?
#include <iostream>
#include <typeinfo>
using namespace std;
int main()
{
int x = 5;
double d = 123.0;
int *ptr_x = &x;
double *ptr_d = &d;
cout << ptr_x << endl;
cout << *ptr_x << endl;
cout << ptr_d << endl;
cout << *ptr_d << endl;
cout << typeid(ptr_d).name() << endl;
return 0;
}
output : 00AFFB68
5
00AFFB58
123
double *
double
형의 포인터 선언하는 경우이고 그에 대한 type도 보여주고 있다.
#include <iostream>
#include <typeinfo>
using namespace std;
int main()
{
int x = 5;
double d = 123.0;
int *ptr_x = &x;
double *ptr_d = &d;
cout << sizeof(x) << endl;
cout << sizeof(d) << endl;
cout << sizeof(&x) << endl;
cout << sizeof(&d) << endl;
return 0;
}
output : 4
8
4
4
???? 뭘까 왜 double
인데 sizeof(&d)
는 4 byte
지? 라고 생각하는 사람들이 있을 수도 있다. '주소'이기 때문에 그렇다. 주소는 4byte
로 이루어져 있기 때문에 어떤 자료형이던 주소는 4byte
로 나오게 된다. 만약, x64
로 바꾼 후에 실행하면 주소를 표현할 때 기본이 8 byte
이므로 모든 자료형의 변수가 8 byte
로 나오게 된다.
포인터를 사용할 때에는 초기화를 '무조건' 해줘라!!!