다른 변수의 메모리 주소를 저장하는 변수이다.
즉, 데이터를 직접 저장하는 변수가 아니라, 그 데이터가 있는 메모리 상의 위치를 가리키는 변수이다.
포인터의 크기는 4 Byte 또는 8 Byte로 정의된다.
두가지 크기로 나뉘는 이유는 우리의 컴퓨터 환경에 따라 달라지기 때문이다.
Window 기반의 컴퓨터는 32bit, 64bit로 나뉜다. 각각 x86, x64로 불리지만 왜 이렇게 나누는지는 다른 글에서 다루기로 하고 포인터와는 어떤 관련이 있는지에 대해서만 다루겠다.
32bit 환경의 컴퓨터는 한번에 처리 가능한 단위가 32bit라는 의미를 가지고 있는데, RAM에서 데이터를 처리할 때 32bit 만큼의 크기를 최대로 처리할 수 있다는 뜻이기도 하다.
즉, 이 크기보다 더 큰 주소 공간은 필요하지 않기 때문에, 주소 공간을 저장하는 포인터 또한 32bit 만큼의 크기를 가지고 있으면 충분하다.
따라서, 32bit 환경의 컴퓨터에서는 4 Byte, 마찬가지로 64bit 환경의 컴퓨터에서는 8 Byte 만큼의 크기를 가지게 된다.
참고로, 32bit == 4Byte이다.
변수 선언 시*심볼을 추가하면 포인터로 사용한다는 의미이다.
이때, 자료형은 포인터에 저장되는 주소에 있는 데이터의 Type과 동일해야 된다.
1. int* ptr1;
2. int *ptr2;
*을 붙이는 위치가 다른데, 이는 코드 스타일 차이로 C++에서 통상적으로 포인터는 타입의 일부로 간주하기 때문에 1번과 같이 선언해 사용한다.
Google C++ style에서도 "포인터를 선언할 때 int* p처럼 타입에 *을 붙여 쓰라고 명시 되어있다.
데이터 Type을 중심으로 생각하면 자료형 앞에
*심볼을 사용해서 포인터 타입을 명확하게 표현할 수 있고, 데이터가 담기는 변수를 중심으로 생각하면 변수명 앞에*심볼을 사용해서 변수 이름으로 의미를 쉽게 파악할 수 있다.
포인터 변수를 선언할 경우에도 다른 Type의 변수들과 마찬가지로 메모리 공간에 새로운 영역을 할당받게 된다.
포인터 변수 사용의 핵심은 다음 두 가지이다.
&" 연산자 : 변수의 메모리상 주소에 접근할때 사용한다.*" 연산자 : 포인터가 가리키는 실제 값에 접근할때 사용한다. 역참조(dereference) 연산자 라고도 부른다.포인터 변수는 변수의 주소를 저장하기 때문에
int a = 10;
int* ptr1 = &a;
처럼 &연산자를 이용해 다른 변수의 주소를 저장하고
printf("%d", *ptr1);
처럼 *연산자를 이용해 포인터 변수인 ptr1에 저장 되어있는 a 공간의 값을 참조해 a값을 불러올 수 있게 된다.
포인터 변수를 초기화하지 않고 쓰거나, 참조중인 변수가 사라질 경우 프로그램 종료, 보안 문제 등의 이슈가 생길 수 있기 때문에 주의해서 사용해야 한다.
포인터로 참조중인 주소 공간이 사라질 수 있는 위험이 있어서 생긴 개념이다.
같은 주소 공간에 다른 이름(변수명)을 붙여 사용이 되고, 메모리 공간에는 할당이 되지 않는다.
사용 방법
reference 변수 선언 시 자료형 앞에 & 심볼을 추가하고, 값 초기화를 한다.
int a = 10;
int& r = a;
printf("%d", r);
변수 선언 시 초기화를 하지 않으면 경고 메세지가 발생한다.
포인터의 포인터 라는 의미를 가지고 있어서 이중포인터 라는 이름으로 불리게 되었다.
다른 공간을 사용하는 포인터 공간을 사용하기 위해 사용된다.
크게 어렵지 않은 개념이다. 기존의 포인터가 변수 공간을 참조하는 역할을 한다면 이중포인터는 변수공간을 참조하는 포인터 공간을 참조한다고 생각하면 된다.
← 기호를 참조라고 생각하면 {변수 A} ← 포인터 변수 ← 이중포인터 변수 인셈이다.
포인터 자료형인 type* 형식의 포인터 이므로 *을 하나 더 붙여서 type** 로 선언해서 사용한다.
마찬가지로 해당 포인터 안의 값을 참조하고 싶으면 **변수명으로 사용하면 된다.