소프트웨어/C 언어

[C언어]33. 예제를 통해 포인터에 능숙해지자.

리습 2013. 11. 12. 16:32


 안녕하십니까. 리습입니다. 


 계속해서 포인터를 공부하고 있습니다. 포인터는 '주소값'을 저장하는 변수공간이며, 공간의 크기는 모두 같으나 타입별로 '참조'하는 크기가 다르다 라고 말씀드렸습니다. 그럼 이런 포인터의 특징을 한번 직접 확인해보도록 하겠습니다.


 4byte 의 변수공간을 만든후 이것을 포인터로 쪼개고 쪼갠 부분들을 재조립하는 코드를 만들어 보겠습니다. 실제로 통신에서 사용되는 방식입니다.


 코드

 

#include <stdio.h>

int main( void )

{

    int box = 333333333;

    char *p1 , *p2;


    int emp_box = 0;

    p1 = (char *)&box; // box의 주소를 p1에 대입, 단 타입이 다르므로 캐스트연산

    p2 = (char *)&emp_box; // emp_box의 주소를 p2에 대입, 단 타입이 다르므로 캐스트연산


    printf("초기값\nbox:     %9d\nemp_box: %9d\n", box, emp_box);

    *p2 = *p1;

    printf("첫번째 \n값 비교\nbox:    %9d\nempbox: %9d\n", box , emp_box);

    printf("16진수 비교\nbox: %14X\nemp_box: %10X \n",box , emp_box);

    *(p2+1) = *(p1+1);

    printf("두번째 \n값 비교\nbox:    %9d\nempbox: %9d\n", box , emp_box);

    printf("16진수 비교\nbox: %14X\nemp_box: %10X \n",box , emp_box);

    *(p2+2) = *(p1+2);

    printf("세번째 \n값 비교\nbox:    %9d\nempbox: %9d\n", box , emp_box);

    printf("16진수 비교\nbox: %14X\nemp_box: %10X \n",box , emp_box);

    *(p2+3) = *(p1+3); 

    printf("네번째 \n값 비교\nbox:    %9d\nempbox: %9d\n", box , emp_box);

    printf("16진수 비교\nbox: %14X\nemp_box: %10X \n",box , emp_box);


    return 0;

}

 결과

 초기값

 box :       333333333

 emp_box:             0

 첫번째

 값비교

 box :      333333333

 empbox :           85

 16진수 비교

 box :        13DE4355

 emp_box:           55

 두번째

 값비교

 box :      333333333

 empbox :     172375

 16진수 비교

 box :        13DE4355

 emp_box:        43555 

 세번째 

 값비교

 box :      333333333

 empbox :  14566229

 16진수 비교

 box :        13DE4355

 emp_box:      DE4355 

 네번째

 값비교

 box :      333333333

 empbox :  33333333

 16진수 비교

 box :        13DE4355

 emp_box:   13DE4355    



 이 코드는 단순히 4바이트 크기의 int 변수 box 와 emp_box를 만든후 1바이트크기에 접근하는 char 타입의 포인터 변수 p1, p2를 가지고 1바이트씩 값을 잘라 옮기는 작업을 합니다. 중간에 많은 printf는  들이 옮겨지는 모습을 보기위해 사용한것 뿐입니다. 가장중요한 코드는 *p2 = *p1 입니다. 포인터 'p1'이 가리키는 공간의 값을 포인터 'p2'가 가리키는 공간의 값에 대입해 주는 것입니다. 후에 *(p2+1) = *(p1+1)을 통해서 1바이트씩 이동하면서 값을 대입하게 됩니다. 이과정을 4번해서 첫번째 바이트부터 네번째 바이트까지 데이터를 대입해 주는 것입니다.  확인은 printf로 출력되는 값을 통해 알수 있습니다. 정수형으로 출력할 경우 쓰레기 값이 보이지만 16진수로 출력하면 13DE4355라는 값이 두자리숫자씩 옮겨지는 것을 볼 수 있습니다.  (16진수는 각 자리가 4비트 씩이므로 두자리씩 옮겨지면 1바이트씩 옮겨지는 것입니다.) 설명은 복잡하나 그림으로 보면 간단합니다.

 우리는 두 공간을 만든 후에 단지 포인터를 사용해 데이터를 옮겨줬을 뿐인것입니다. char 타입의 포인터를 이용해서 4바이트크기의 box 변수를 1바이트씩 참조하여 emp_box 변수에 p2를 통해서 넣어준것입니다. 분명한것은 1바이트씩 변수의 내부 내용이 옮겨지고 있다는 것입니다. 만약 2바이트의 참조 크기를 가지는 포인터 변수를 사용했다면 16진수로 나타낸 숫자는 4자리숫자씩 옮겨 졌겠죠. 


 이런 코드는 실제로 통신을 할때 한정된 데이터만 한번에 보낼수 있는 경우 사용됩니다. 크기가 큰 데이터를 잘라서 보내게 되는 것이죠. 물론 이런 사항까지 알아둘 필요는 없지만 지금은 포인터가 어떻게 사용되며 포인터를 이용하면 이런 일도 할수있다. 라는 것 정도만 확실하게 이해하시면 됩니다. 


 *포인터 변수의 타입은 접근하는(참조하는) 크기만을 가리킬 뿐 어떠한 데이터라도 가리킬 수 있으며 포인터를 이용해서 큰 데이터도 쪼개서 관리할 수 있다.