C언어(2020년)

17. 포인터

리더2333 2020. 11. 3. 13:44
반응형
#include <stdio.h>

int main()
{
	int* pointer = 0;
	printf("%d\n", sizeof(pointer));
	printf("%d\n", sizeof(int*));
}

포인터 변수를 선언할 때에는

(자료형) * (포인트변수명);

이렇게 선언되어진다.

int* pointer;

int * pointer;

int *pointer;

모두 같은 의미 이다.

sizeof() 함수는 크기를 byte 단위로 반환해주는 함수이다.

 

Visual Studio 상단메뉴에서 x86 으로 설정한 후 실행하면

sizeof(pointer) 나 sizeof(int*) 의 값은 4가 된다. 4byte 를 의미한다.

 

x64 로 설정후에 실행하면

sizeof(pointer) 나 sizeof(int*) 의 값은 8이 된다. 8byte 를 의미한다.

 

x86 이란 32비트 컴퓨터를 의미하며,

x64 이란 64비트 컴퓨터를 의미한다.

 

32비트 컴퓨터에서는 주소를 담을 수 있는 포인터의 저장공간이 4byte 로 할당된다.

이것은 32비트 컴퓨터에서는 최대 16GByte 의 RAM을 가질 수 있음을 의미한다.

왜 그런지 알아보자.

더보기

포인터 변수가 4byte 라는 것은 무엇을 의미하는가

그리고 왜 4byte 인가??

 

32비트 컴퓨터랑 한번에 32비트씩 연산을 한다는 의미이다.

CPU는 한번에 32비트씩 연산을 하겠지.

32비트란 바이트로 4byte이기 때문에, 포인터 변수를 4byte 로 해야 한번에 처리가 가능하겠지.

하여 포인트 변수는 4byte이다.

 

그럼 포인터 변수가 가질 수 있는 수의 범위는 0xffffffff 개 이다.

(int 가 4byte 이므로 약 42억 까지 가질 수 있는것과 같다)

정확히 0xffffffff 이란 숫자는 4294967295 이런 숫자이다(42억 9496만 7295)

0x00000000 도 있으니 총 4294967296 개의 주소를 표현할 수 있다.

4294967296개 * 4바이트 = 17179869184 바이트

17179869184 / 1024 = 16777216 KByte

16777216 / 1024 = 16384 MByte

16384 / 1024 = 16 GByte

 

만약 RAM 이 16 GByte 보다 크면 4byte 짜리인 포인터 변수에 16GByte 이상의 주소값을 넣을 수가 없다.

 

 

64비트 컴퓨터는 어떨까?

더보기

64비트 컴퓨터는 한번에 64비트씩 처리하고

포인트 변수도 64비트 이기 때문에 총 0x0000000000000000 ~ 0xffffffffffffffff 까지 표현할 수 있다.

0xffffffffffffffff 은 십진수로 18446744073709551615 을 의미하고 0을 포함하면

18446744073709551616 개 가 된다. 1개가 4byte 이므로

18446744073709551615 * 4 = 7.3786976e+19 Byte

7.3786976e+19 / 1024 = 7.2057594e+16 KByte

7.2057594e+16 / 1024 = 7.0368744e+13 MByte

7.0368744e+13 / 1024 = 68719476736 GByte

68719476736 / 1024 = 67108864 TByte

67108864 / 1024 = 65536 PByte (페타바이트)

65536 / 1024 = 64 EByte (엑사바이트)

 

64 EByte (엑사바이트) 의 RAM 까지 가질 수 있다.

만약 시대가 흘러 64 EByte(엑사바이트) 의 용량이 부족하게 되면

 

128비트 컴퓨터를 개발 하겠지

 

지금은 RAM 메모리를 얘기 하는 것이다.

용량이 커진다고 하드디스크와 헷갈리면 안된다.

 

 

 

 

#include <stdio.h>

int main()
{
	char* pointer = 0;
	printf("%d\n", sizeof(pointer));
	printf("%d\n", sizeof(char*));
}

결과는 4 이다.

char 형 포인트 변수의 크기역시 4이다.

(물론 64비트 에서는 8)

 

int 자료형은 4바이트이고 char 자료형은 1byte 인데,

int* 는 4 바이트이고 char* 는 4 바이트이다.

 

그냥 포인터 변수는 4바이트이다.

왜냐하면 32비트 컴퓨터이기 때문이고,

주소의 값을 나타내야 하기 때문이다.

 

그럼 char* 와 int* 는 어떤 차이가 있을까?

#include <stdio.h>

int main()
{
	char num1[10] = { 0,1,2,3,4,5,6,7,8,9 };
	int num2[10] = { 10,11,12,13,14,15,16,17,18,19 };

	char* p1 = &num1[0];
	int* p2 = &num2[0];

	printf("%x, %x\n", p1, p2);
	p1++;
	p2++;
	printf("%x, %x\n", p1, p2);
}

실행 결과

char* 형 포인터 변수 p1 에 num1 배열의 첫번째 주소를 넣고

int* 형 포인터 변수 p2 에 num2 배열의 첫번째 주소를 넣은 후에

주소값을 출력하고,

p1, p2 포인터 변수를 각각 ++ 시킨후에

주소값을 출력하였더니

 

p1 은 1(byte)만큼 주소가 변경되었고,

p2 는 4(byte)만큼 주소가 변경되었음을 알 수있다.

 

즉, char* 나 int* 모두 4 바이트의 저장공간을 가지고 있으나,

char* 의 변수의 경우 ++ 했을 때 주소가 1 byte 증가하였고,

int* 의 변수의 경우 ++ 했을 때 주소가 4 byte 증가했다는 것이다.

 

어찌보면 당연하다. 

char 변수는 용량이 1byte 이기 때문에 1byte 씩 증가 해야 하고,

int 변수는 용량이 4byte 이기 때문에 4byte 씩 증가 해야 한다.

반응형

'C언어(2020년)' 카테고리의 다른 글

19. 연산자  (0) 2020.11.03
18. 연산자 우선순위  (0) 2020.11.03
16. RAM 에 대한 고찰  (0) 2020.11.03
15. 주석  (0) 2020.11.03
14. 배열  (0) 2020.11.02