C 언어에서 포인터 변수는 각각의 자료형에 대응하는 포인터 자료형을 선언(char → char *, int → int *)한다. 하지만, 사실상 모든 포인터 변수가 4 Byte 크기의 표현 범위를 가지고 있으므로 일반 변수의 주소 값을 대입하는 것에 대한 문제는 없을 것이다.


포인터 변수 자료형에 대하여 동일한 크기를 가지는 이유에 대해서는 이전 포스팅에서 설명하였다.
(2017/09/16 - [Programming/C] - C 언어 모든 포인터 변수 자료형이 똑같은 크기를 가지는 이유)

 

 

그렇다면 포인터 변수 자료형을 따로 두는 이유는 무엇일까? 이 부분에 대해서 포인터 자료형에 대하여 메모리에 접근하는 방식을 다뤄본다. 각 포인터 변수 자료형에서 메모리를 어떻게 읽어드리는지 확인하기 위해 아래와 같은 예시 코드를 작성하였다.

int 형 정수 변수에 임의의 수인 671,482,627를 입력하고, 해당 변수에 대하여 (char *), (short *), (int *) 자료형에 대하여 어떠한 값이 출력되는지 확인하는 코드이다.

 


 

위의 예시 코드를 컴파일하여 실행한 결과이다.

 


 

이를 메모리상에 도식한 형태는 아래와 같다.

 


 

이를 각각의 포인터 자료형에 맞게 정리하여 표현한다면, 아래와 같은 형태로 각각의 포인터 자료형이 지정된 크기에 맞게 메모리를 읽어드리는 것을 확인할 수 있다.

 


 

출력된 결과를 바탕으로 정리를 해보면 아래 그림과 같은 방식으로 정리가 될 것이다. (char *)의 경우 선언된 메모리 시작 주소에서 1 Byte 크기의 메모리 크기를 읽어드리고 이를 출력한다. 마찬가지로 (short *)의 경우도 선언된 메모리 시작 주소에서 2 Byte 크기씩 메모리를 읽어드려 값을 표현한다.
위의 그림의 메모리 주소를 자세히 보면, 메모리 순서가 역으로 표현되어 있는 것을 확인할 수 있다.

가령 (short *)인 2 Byte의 경우, 데이터 표현이 0xbfe30846~0xbfe30847가 아닌, 0xbfe30847~0xbfe30846​ 역순으로 표현되고 있으며, (int *)인 4 Byte의 경우도 0xbfe30844~0xbfe30847가 아닌, 0xbfe30847~0xbfe30844​의 순서로 값이 표현되었다.

 - 참고) 만약 정방향의 순서로 값을 읽어드려 (int *) 4 Byte를 표현한다면, 0xbfe30844~0xbfe30847 = 50,529,832 값이어야 한다.

 

그 이유로는 현재 사용되는 CPU에서는 지정된 포인터의 크기만큼 메모리를 읽어드릴 때, 이를 역으로 읽어서 데이터를 표현하게 되는데 이를 Little Endian 표기법이라고 하며, 아래 그림은 다음 설명한 내용을 Little Endian 표기법​으로 정리하여 요약한 것이다.

 


 

다음과 같이 포인터 변수마다 각각의 고유 자료형 이름을 가지는 이유는 변수가 시작되는 주소 값에서 얼마만큼의 크기를 읽어드릴지 위한 단위의 지정​하기 위함​임을 알 수 있다.

 

+ Recent posts