포인터 변수를 sizeof 함수를 이용하여 사이즈 체크해보면 8바이트로 표기된다.
int* pInt = nullptr;
char* pChar = nullptr;
int sizeInt = sizeof(pInt);
int sizeChar = sizeof(pChar);
printf("int와 char 포인터 변수의 크기 : %d, %d\n", sizeInt, sizeChar);
// int와 char 포인터 변수의 크기 : 8, 8
포인터 변수가 8바이트인 이유를 알려면 먼저 윈도우의 비트 지원에 대해 짚고 넘어가야한다.
현재 대부분의 PC들은 64비트를 지원하고 있다. 이전에는 32비트를 지원하였는데 32비트의 OS메모리 크기는 , 4,294,967,296byte가 된다. 이는 4,194,304KB == 4,096MB == 4GB의 메모리 용량을 제공한다는 것이다.
다시말해 메모리가 4GB만 되어도 충분했다는 것이다. 그래서 32비트 윈도우 환경에서는 주소를 최대 표현할 수 있는 수인 4바이트(32비트)로 포인터 변수의 크기가 결정되었다.
그러나 애플리케이션의 크기가 커지고 하드웨어가 발전하면서 4GB만 제공하는 것은 제한적이였는데 64비트 환경의 윈도우 환경이 등장하고 그 제한사항은 해소가 되었다. 메모리 용량적으로 64비트는
, 18,446,744,073,709,551,616byte 크기를 제공하고 18,014,398,509,481,984KB == 17,592,186,044,416MB == 17,179,869,184GB == 16,777,216TB == 16,38PB == 16EB단위까지 제공하게 되었다.
늘어난 윈도우 비트 수만큼 포인터 변수의 크기도 증가하였는데 64비트의 주소값을 표현가능한 8바이트가 된 것이다.
이러한 배열의 특징은 포인터 변수를 활용할 때 두드러지게 나타난다.
int형 배열을 선언해주고, 인덱스 4 이후부터 0이 담길것이다.
int iArray[10] = {1,2,3,4,5};
//포인터 변수를 선언 및 할당.
int* pInt = iArray;
printf("배열 값 : %d\n", *pInt); // 1
포인터 변수에 배열 변수를 넣으면 해당 배열의 첫번째 주소값을 넣는 것과 동일한 효과를 볼 수 있다. 따라서 포인터 변수의 값을 출력하면 첫번재 인덱스 값을 출력할 수 있다.
*(pInt + 6) = 10;
위 코드를 실행하면 이는 6번째 배열의 값을 10을 넣으라는 것과 동일하다.
//문제1
short sArr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//short 2byte를 int형의 포인터 변수에 강제로 할당.
int* pI = (int*)sArr;
// pI에 2를 증가시키면 8바이트가 증가됨.
//short로 다시 캐스팅하여 8바이트, 4칸 증가.
int iData = *((short*)(pI + 2));
//iData에는 5를 출력함.
printf("%d\n", iData);
//문제2
// char 1바이트임.
char cArr[2] = { 1,1 };
//short타입의 포인터 변수에 short타입으로 강제로 할당
short* pS = (short*)cArr;
// 주소는 이동하지 않았음. 첫번째 주소는 그대로 사용
// char의 배열은 (0000 0001) (0000 0001)이렇게 담겨있다.
// short는 2바이트로 접근하기에
// short 타입은 2바이트 16비트임, //0000 0001 0000 0001 로 해석한다.
// 256에 1 더한 257이 됨.
iData = *pS;
함수의 매개변수에 포인터 변수를 전달하면 이는 Call By Reference라고 한다.
주소로 받아야 되니 주소를 받는 매개변수를 포인터 변수로 입력한다.
//주소로 매개변수로 받는 함수 정의 부분에서는 포인터 변수로 받고
void Test(int* a){
// 포인터 변수로 자료 수정.
*a = 500;
};
int main(){
int a = 100;
//변수 a의 주소를 전달.
Test(&a);
printf("%d", a); // 500
return 0;
}
위와 같이 특정 값을 전달하는 방식이 아닌 참조를 전달하게 되면 다른 스택에서 처리가 되더라도 주소는 원래의 변수가 참조하고 있으니 정적변수나 외부변수가 아니더라도 수정할 수 있게 된다.