ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [C Language] 42. void형 포인터 - C 언어
    CSE/C Language 2015. 8. 5. 14:33

    1. void 형 포인터란?

     널 포인터가 포인터임에도 불구하고 어느 곳도 가리키고 있지 않는 데 반해, void 형 포인터는 무엇이든 가리킬 수 있는 포인터이다.

     널 포인터가 아무것도 넣을 수 없는 자루라면 void 형 포인터는 무엇이든 들어가는 자루이다.


      void 형 포인터는 현재 가리키고 있는 대상체가 정해져 있지 않는 포인터이다.


     바꾸어 말하면 현재 가리키는 대상체가 정해져 있지 않기 때문에 대상체만 정해지면 얼마든지 사용할 수 있다는 의미이다.







    2. void 형 포인터 변수 정의

     char 형 포인터는 'char *' 로 표기할 수 있고 int 형 포인터는 'int *'로 표기할 수 있다. 마찬가지로 void 형 포인터는 'void *'로 표기한다.



      void   *void_p; 



     void_p는 포인터 변수이기 때문에 당연히 메모리에 4 바이트가 할당된다. 또한, 포인터 변수이기 때문에 주소 값 이외에는 할당될 수 없다. 그렇다면 void_p가 가리키는 값은 어떤 형일까? 

     지금까지는 포인터 변수를 정의할 때 포인터 변수 앞에 형을 지정함으로써 형을 명시했다. 

     void 형 포인터 변수는 정의할 때 아무것도 가리키고 있지 않다는 의미로 'void *'로 지정했기 때문에 현재는 무엇을 가르키고 있는지 알 수 없다. void 형 포인터 변수를 사용할 때 포인터 변수가 가리킬 형이 프로그램을 진행하면서 정해지는 이유가 이것 때문이다.






    3. void 형 포인터의 성질

     void 형 포인터는 다음과 같은 성질이 있다.


     - 어떠한 형 변환(cast 연산자) 없이도 void 형 포인터 변수에 주소 값을 할당할 수 있다.

     - void 형 포인터 변수에서 값을 읽을 때는 반드시 캐스트 연산자를 사용해야 한다.

     - '*' 연산자(간접 지정 연산자)를 사용할 때는 항상 캐스트 연산자를 사용해야 한다.

     - void 형 포인터 변수에 ++, --를 사용할 때는 항상 캐스트 연산자를 사용해야 한다.


     위의 void 형 포인터 변수 성질들은 원리만 알면 너무도 당연한 내용이므로 굳이 외우려고 할 필요가 없다. 


     - 어떠한 형 변환(cast 연산자) 없이도 void 형 포인터 변수에 주소 값을 할당할 수 있다.


    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
     
    /*
     * voidp.c
     *
     *  Created on: 2015. 8. 5.
     *      Author: Yeonsu
     */
     
    #include <stdio.h>
     
    int main(void) {
     
        int num = 123;
        float num_f = 56.6;
        char text_c = 'M';
     
        void *void_p;
     
        void_p = &num;
        void_p = &num_f;
        void_p = &text_c;
     
        return 0;
    }
     
    cs




     컴파일을 해보면 에러가 발생하지 않는다. 위의 예제로 확인할 수 있는 것은 void 형 포인터 변수에 주소 값을 대입할 때는 어떠한 형 변환도 필요없다는 것이다.

     



     - void 형 포인터 변수에서 값을 읽을 때는 반드시 캐스트 연산자를 사용해야 한다.

     






     여러분이 다른 사람의 집을 방문했다고 가정해 보자. 닭고기가 너무 먹고 싶어서 냉장고 문을 열었다. 100% 닭고기를 냉장고에서 꺼낼 수 있는 경우는 여러분이 닭고기를 넣은경우와 다른 사람이 닭고기 넣는 것을 본 경우이다. 

     void 형 포인터 변수도 마찬가지다. void 형 포인터가 냉장고라 할 때 그곳에서 int 형을 꺼내려고 한다면 그곳에 여러분이 int형을 넣든지 넣은 것을 본 경우이다. 프로그램은 다른 사람이 대신 작성해 주는 것이 아니므로 전자가 이에 해당된다. 결론을 말하면 void 형 포인터 변수에서 무언가를 꺼내려고 한다면 그 안에 무엇이 들어 있는지 미리 알아야 한다는 것이다. void 형 포인터 변수에 무엇이 들어 있는지 모르는 상태에서 무조건 꺼내려고 한다면 원하지 않는 결과를 얻을 것이다.



    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
     
    /*
     * voidp.c
     *
     *  Created on: 2015. 8. 5.
     *      Author: Yeonsu
     */
     
    #include <stdio.h>
     
    int main(void) {
     
        int num = 123;
        float num_f = 56.6;
        char text_c = 'M';
     
        void *void_p;
     
        void_p = &num;
        printf("int %d\n"*((int *) void_p));
     
        void_p = &num_f;
        printf("float %f\n"*((float *) void_p));
     
        void_p = &text_c;
        printf("char %c\n"*((char *) void_p));
     
        return 0;
    }
     
    cs










     - '*' 연산자(간접 지정 연산자)를 사용할 때는 항상 캐스트 연산자를 사용해야 한다.

     포인터 변수에 '*' 연산자를 사용한다는 의미는 포인터 변수에 할당된 주소를 참조하여 값을 구하는 것이다. 값을 구하려면 그 값이 int 형인지 double 형인지 알아야 주소 값에서 4, 8 바이트를 읽어 올 수 있다. 그러므로 void 형 포인터에서 '*' 연산자를 사용할 때는 항상 캐스트 연산자가 필요하다. 바로 전 예제를 보면 int 형 123을 얻기 위해 '*'를 사용했고 '*'를 사용하기 위해서 캐스트 연산자가 사용되었다. 캐스트 연산자를 사용하지 않으면 주소가 가리키는 곳에서부터 몇 바이트를 읽어 올지 알 수 없으므로 void 형 포인터에서 값을 취할 때는 캐스트 연산자가 반드시 필요하다.





     - void 형 포인터 변수에 ++, --를 사용할 때는 항상 캐스트 연산자를 사용해야 한다.

     ++ 이나 -- 의 의미는 x = x + 1 이나 x = x - 1과 같은 수식을 줄여서 사용한 것이다. x = x + 1을 사용하려면 x 에서 값을 구하고 여기서 1 을 더한 후 다시 x 에 넣어야 한다. x 에서 값을 구하려면 형이 정해져야 하고 형이 정해지기 위해서는 캐스트 연산자의 사용이 필수적인 것이다.



     


    댓글

Designed by Tistory.