Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

nomad-programmer

[C] void 형 포인터 본문

Programming/C

[C] void 형 포인터

scii 2020. 6. 9. 19:57

대상의 크기가 정해져 있지 않은 void *형 포인터

대상의 크기를 모른다면? 이때 사용하는 것이 바로 void 키워드이다. void 키워드는 '정해져 있지 않다'는 의미를 가지고 있다. 

void* ptr; 이렇게 선언하면 ptr에 주소 값을 저장할 수는 있지만 해당 주소에서 값을 읽거나 저장할 때 사용하는 크기는 정해져 있지 않다. 즉 사용할 메모리의 시작 주소만 알고 끝 주소를 모를 때 사용하는 포인터 형식이다.

void 포인터는 가리킬 대상의 크기를 정한 것이 아니라서 어떤 크기의 메모리가 오든지 상관 없다. 그렇다면 void * 로 선언한 포인터 변수를 주소 값만 저장하는 용도로 사용하는 것은 아니다. 적절한 형 변환을 거쳐 '사용할 크기'를 표기해 주면 일반 포인터처럼 사용할 수 있다.

int main(void){
    int data = 0x12345678;
    void* ptr = &data;
    
    *(short*)ptr = 255;
    
    printf("%d, %d", *(short*)ptr, *(char*)ptr);
    
    return 0;
}

// 결과
/*
255, -1
*/

위의 예제를 살펴보면, void형 포인터를 short형으로 변환한 후 short형 크기 만큼의 메모리 공간에 255 값을 대입하였다. 이것을 void 포인터로 적절한 형 변환을 거쳐 출력하고 있다. short형 크기 만큼 크기를 결정해 나오는 값은 255 같은 값이 나온다. 

허나 char형으로 형 변환한 후 나오는 결과는 -1이 나온다. 그 이유는 

00000000 11111111 (0x00FF) 이렇게 255 값이 저장되었는데 char형으로 형 변환하여 가져온 값은 11111111 (0xFF) 이기 때문이다. (windows 시스템은 리틀 엔디안이므로)

그래서 -1의 값이 나온다.

 

void 형 포인터 활용

void 포인터는 자신이 사용할 대상의 크기 지정을 잠시 미룰 수 있다는 장점이 있다. 예를 들어 char형 주소 값을 저장하려면 char형 포인터 변수가 있어야 하고 int형 주소 값을 저장하려면 int형 포인터가 변수가 있어야 한다.

하지만 void형 포인터 변수는 char형이든 int형이든 형 변환 없이 모두 저장할 수 있기 때문에 편리하다.

더보기

NULL 은 C언어 기본 헤어 파일에 #define으로 정의되어 있으며 0번지를 의미한다. 그래서 일반 변수는 초기화할 때 0을 대입하지만 포인터 변수는 초기화할 때 0번지를 의미하는 NULL 을 사용해야 한다.

void MyFunc(void* ptr, char flag) {
    if (0 == flag) {
        *(char*)ptr = 1;
    }
    else if (1 == flag) {
        *(short*)ptr = 1;
    }
    else {
        *(int*)ptr = 1;
    }
}

int main(void) {
    short data = 5;

    MyFunc(&data, 1);

    printf("%d", data);

    return 0;
}
Comments