본문 바로가기

Education

[부스트 코딩 뉴비 챌린지 2020] C언어: 포인터에 자료형은 왜 붙일까?

반응형

이번주 6주차 마지막 미션 회의를 하면서 가진 의문이다. 

팀원 중 한 분이 int형 포인터는 할당되는 메모리 크기가 int크기인 4임을 의미하는 게 맞냐는 질문을 했다. 하지만 포인터 변수는 가리키는 변수의 메모리 주소를 저장하고 있으므로 운영체제에 따라 항상 4 / 8바이트의 정해진 크기를 갖는다.

그렇다면 포인터 변수 앞에 자료형은 왜 붙일까? 그냥 간편하게 포인터 자료형이라고 따로 만들면 될텐데 말이다.

 

포인터에 저장되는 메모리 주소값은 정수형으로 동일(4 or 8 bytes)하지만, 선언하는 자료형에 따라 메모리에 접근하는 방법이 달라진다고 한다. 즉, 아래와 같이 포인터를 역참조하게 되면 선언한 자료형의 크기에 맞춰 값을 가져오거나 저장하게 된다.

즉, long long 포인터는 8바이트 크기만큼 값을 가져오거나 저장하고, char 포인터는 1바이트 크기만큼 값을 가져오거나 저장한다.

 

그렇다면 포인터 자료형에 따라 메모리에 접근하는 방식이 어떻게 다를까? 

포인터의 자료형에 따라 어떤 메모리 주소값이 저장되는지 알아보기 위해 아래와 같인 예시 코드를 보자. int형 정수 변수에 임의의 수를 넣고, 해당 변수에 대해 (char*), (short*), (int*) 자료형에 대해 어떤 값이 출력되는지 알아본다.

#include <stdio.h>

int main(){
    int temp = 91203;
    int i;

    void *vptemp = &temp;
    char *cptemp = vptemp;
    short *sptemp = vptemp;
    int *iptemp = vptemp;


    printf("temp address: %p\n\n", vptemp);

    for(i = 0; i < 4; i++){
        printf("cptemp+%d : %p\n", i, cptemp+i);
    }

    for(i = 0; i < 4; i++){
        printf("*(cptemp+%d) : %d\n", i, *(cptemp+i));
    }

    for(i = 0; i < 2; i++){
        printf("*(sptemp+%d) : %d\n", i, *(sptemp+i));
    }

    printf("*(iptemp+0) : %d\n", *(iptemp+0));
}
temp address: 0x7ffd952c7178

cptemp+0 : 0x7ffd952c7178
cptemp+1 : 0x7ffd952c7179
cptemp+2 : 0x7ffd952c717a
cptemp+3 : 0x7ffd952c717b

*(cptemp+0) : 67
*(cptemp+1) : 100
*(cptemp+2) : 1
*(cptemp+3) : 0

*(sptemp+0) : 25667
*(sptemp+1) : 1

*(iptemp+0) : 91203

 

   
(int *) 91203
(short *) 1 25667
(char *) 0 1 100 67
- 00000000 0000001 01100100 01000011
- 0x7ffd952c717b 0x7ffd952c717a 0x7ffd952c7179 0x7ffd952c7178

위의 코드 작성 결과와 표를 보자.

(char *)의 경우, 메모리 크기를 1Byte(=8bits) 읽고 이를 출력한다. (short*)는 2bytes(=16bits)의 메모리 크기를 읽고 출력하며, (int *)의 경우 4bytes(=32bits)의 메모리 크기를 읽고 값을 표현한다.

 

하지만 표에서도 알아차렸듯이, 메모리의 주소를 자세히 살펴보면 메모리의 순서가 역으로 되어 있다는 것을 확인할 수 있다. 그 이유는 현재 사용되는 CPU에서는 지정된 포인터의 크기만큼 메모리를 읽을 때, 이를 역으로 읽어서 데이터를 표현한다. 이를 "Little Endian 표기법"이라고 한다. 

Little Endian 표기법

 

앞선 질문에 요약하자면, 앞에서도 말했듯이 포인터 변수마다 각각의 고유 자료형 이름을 가지는 이유는 변수가 시작되는 주소 값에서 얼마만큼의 크기를 읽어드릴지를 결정하기 위해 단위를 지정하기 위함이다.

 


출처 :

 

C 언어 코딩 도장: 34.4 다양한 자료형의 포인터 선언하기

지금까지 int 포인터를 선언했습니다. 이번에는 다양한 자료형의 포인터를 선언해보겠습니다. pointer_type.c #include int main() { long long *numPtr1; // long long형 포인터 선언 float *numPtr2; // float형 포인터 선

dojang.io

 

C 언어 포인터 변수 자료형이 필요한 이유

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

programist.tistory.com

 

반응형