포인터
#include <iostream>
using namespace std;
int main(void)
{
int a = 10;
int* b = &a;
int** c = &b;
printf("변수 a의 메모리 주소 : %p\n", &a);
printf("포인터 변수 b의 값 : %p\n", b);
printf("포인터 변수 c의 참조 값 : %p\n\n", *c);
// 세 출력 값은 모두 같다.
printf("변수 a의 값 : %d\n", a);
printf("포인터 변수 b의 참조 값 : %d\n", *b);
printf("포인터 변수 c의 이중 참조 값 : %d\n", **c);
// 세 출력 값은 모두 같다.
return 0;
}
'포인터'는 '메모리 주소를 저장하는 자료형'입니다. 모든 자료형에 애스터리스크 ( * )를 붙이면 포인터 자료형으로 선언할 수 있습니다. 포인터의 메모리 크기는 빌드할 때 어떤 플랫폼으로 빌드하느냐에 따라 달라집니다. 기본적으로 32bit 프로그램은 포인터가 4Byte의 메모리 공간을 차지하고 64bit 프로그램은 8Byte의 메모리 공간을 차지합니다.
포인터에 메모리 주소를 넣을 때 포인터가 아닌 변수에 '& ( Ampersand )'를 붙여서 메모리 주소를 받아올 수 있습니다. 또한 동적 할당을 통해 메모리에 공간을 할당할 때 반환 값이 메모리 주소가 나오는데, 이 값을 포인터로 받아서 관리할 수 있습니다.
그렇게 받아온 메모리 주소를 참조 연산자 ( 애스터리스크 *, 포인터 자료형을 선언할 때 사용하는 것과 같지만 용도는 다릅니다. )를 사용하여 접근할 수 있게 됩니다. 예시 코드에서 int 포인터 변수 b에 int 변수 a의 주소 값을 받아서 *b로 접근하게 되면 a에 저장된 값 '10'을 b에서도 쓸 수 있게 됩니다.
포인터의 메모리 주소 ( 예시 코드에서는 b의 메모리 주소 )도 저장할 수 있는 방법이 있는데, 이것을 '이중포인터'라고 합니다. 예시 코드에서 포인터 변수 b의 주소를 받는 int** c라는 변수가 있습니다. 이것이 이중 포인터 변수이고 저장된 포인터 변수의 메모리 주소를 통해 또 다른 주소로 접근할 수 있게 됩니다.
스크린샷에서 보이는 0x00000001BE0FF7A4가 변수 a의 메모리 주소입니다. 0000000a ( 10진법으로 10 )는 변수 a 안에 담긴 값이 16진법으로 표현된 것입니다. a가 코드에서 10이었으므로 정상적으로 값이 담아졌고, 그런 a를 가리키는 포인터 b의 값에 be0ff7a4 00000001이 담겨있는 것을 볼 수 있습니다. 64bit 프로그램이라서 포인터 변수가 8Byte 공간을 사용했습니다.
b의 값이 00000001 BE0FF7A4이 아닌 be0ff7a4 00000001인 이유는 리틀 엔디안 방식이라서 그렇습니다. 원래는 1Byte 단위로 뒤집혀 있지만 편의를 위해 4Byte 묶음으로 보게 설정해두어서 8Byte인 포인터 변수가 반만 뒤집혀 있는 상황입니다.
마찬가지로 c에도 b의 메모리 주소가 담겨있는 것을 확인하실 수 있습니다. 왼쪽에 적힌 0x00000001BE0FF7C4를 기준으로 4Byte 더 옆 공간에 자리하고 있는 00000001 be0ff7c8을 가리키고 있는 것을 확인할 수 있습니다.
포인터는 산술 연산도 일부 가능합니다. 예시 스크린샷에서 b에 1을 더하면 ( b++나 ++b도 가능하고 b + 1도 가능합니다. ) a 변수 오른쪽의 공간을 가리키게 됩니다. 현재는 cccccccc란 값이 들어있음으로 의미가 없지만 배열 형태의 구조에서는 유용한 연산입니다.
반대로 1을 빼면 왼쪽 주소로 이동하게 되고 이동할 때 이동하는 거리의 기준은 포인터 변수의 자료형에 따라 다릅니다. 예시에서는 int 포인터 변수였기 때문에 4Byte씩 이동하지만, 만약 char형 변수였다면 1Byte씩 이동하게 됩니다.
또, 포인터끼리의 뺄셈도 가능합니다. a의 오른쪽 공간을 가리키고 있는 포인터 변수 e가 있다고 가정하고 a를 가리키는 포인터 b와 뺄셈 ( e - b )을 하면 1이라는 값이 나오게 됩니다. 이것은 두 포인터 변수가 4Byte 기준으로 1만큼의 거리 차이가 있다는 것을 의미합니다. ( 순서를 뒤집어서 b - e 를 하면 -1이 나옵니다. )
'C & C++' 카테고리의 다른 글
C/C++ 기초 - 변수 ( Variable ) (0) | 2021.10.17 |
---|---|
C/C++ 기초 - 함수 ( Function ) (0) | 2021.10.17 |
C/C++ 기초 - 배열 ( Array ) (0) | 2021.10.12 |
C/C++ 기초 - 문 (Statement) (0) | 2021.10.10 |
C/C++ 기초 - 연산자 ( Operator ) (0) | 2021.10.10 |