상세 컨텐츠

본문 제목

Pointer 분석 (1) - 값과 주소의 이동파악

C 언어

by ChrisMare 2018. 1. 5. 11:08

본문

* 다음 나오는 코드를 손 코딩으로 예상해서 포인터연산을 분석 해 보면 조금 더 쉽게 접근할 수 있습니다.



#include <stdio.h>


void main() {

int *ptr;

int n[] = { 5, 10, 22, 34, 36, 44 };

ptr = n;


printf("%d ", *ptr++);   printf(" %d\n", *ptr);

printf("%d ", *ptr + 1);         printf(" %d\n", *ptr);

printf("%d ", ++*ptr); printf(" %d\n", *ptr);

printf("%d ", *(ptr + 1));         printf(" %d\n", *ptr);

printf("%d ", *ptr += 1);         printf(" %d\n", *ptr);

printf("%d ", *++ptr);   printf(" %d\n", *ptr);

printf("%d ", (*ptr)++);         printf(" %d\n", *ptr);


return;

}


==========================================================================================


ptr -> n[0]

 0

 1

 2

 3

 4

5

 5

10 

22 

34 

36 

44 



ptr이 가르키는 곳은 n 입니다.


       1) printf("%d ", *ptr++);   printf(" %d\n", *ptr);



*ptr++ => 변수 ptr을 기준으로 오른쪽 ++를 먼저 봅니다. ptr++ -> ptr = ptr + 1; 하지만 ptr++은 후처리 이기 때문에 printf명령이 끝난 후 실행하게 됩니다. 따라서 변수 ptr을 기준으로 왼쪽 * 로 인해 먼저 그 주소의 값을 찍습니다. 그리고 printf명령이 끝나고 ptr++을 실행 해서 ptr의 주소가 다음 요소로 넘어 갑니다. 

따라서, ptr = ptr + 1;    ptr -> n[1]      


Output    :    (  5        10  )


ptr -> n[1]

 0

 1

 2

 3

 4

5

 5

10 

22 

34 

36 

44 


==========================================================================================


       2) printf("%d ", *ptr + 1);         printf(" %d\n", *ptr);


ptr은 n[1]요소를 가르키고 있습니다. 따라서 *ptr은 ptr이 가르키는 값이고 여기에 +1 해서 11을 찍습니다.

하지만, ptr이 11로 증가하는 것이 아니라 그냥 연산만해서 찍는 것이고 실제로 ptr은 변화가 없는 10입니다.


Output    :    (    11        10    )


==========================================================================================


       3) printf("%d ", ++*ptr); printf(" %d\n", *ptr);


ptr 변수를 기준으로 *를 적용해서 ptr이 가르키는 값에다가 ++를 적용합니다,

따라서 ++*ptr ->     *ptr = *ptr + 1; 입니다. 그로 인해 ptr이 가르키는 곳의 값이 바뀌게 됩니다.


Output    :    (    11        11    )


ptr -> n[1]

 0

 1

 2

 3

 4

5

 5

10->11 

22 

34 

36 

44 



==========================================================================================


       4) printf("%d ", *(ptr + 1));         printf(" %d\n", *ptr);


ptr을 기준으로 오른쪽 +1을 합니다. 이것은 ptr이라는 주소를 다음 요소를 가르키게 합니다.

실제로는 ptr은 n[1]을 가르키고 변경이 없지만 (ptr + 1)주소에다가 *를 해서 그곳의 값을 찍으라고 하는 것과 같습니다. 따라서 ptr은 n[1]을 가르키지만 여기서는 ptr+1이라서 n[2]를 가르킵니다.


Output    :    (    22        11    )


==========================================================================================


       5) printf("%d ", *ptr += 1);         printf(" %d\n", *ptr);


간단히 예로 a += 1 일 경우) a = a+1;과 같은것 처럼

여기서도 *ptr을 a라보고 따라서 *ptr = *ptr+1;과 같습니다.

따라서 여기서도 ptr이 가르키는 곳의 값이 +1 증가합니다.


Output    :    (    12        12    )


ptr -> n[1]

 0

 1

 2

 3

 4

5

 5

11->12

22 

34 

36 

44 


==========================================================================================


       6) printf("%d ", *++ptr);   printf(" %d\n", *ptr);


ptr을 기준으로 오른쪽이 없으니 왼쪽 ++을 선처리로 계산합니다. 따라서 printf가 실행되기전에 먼저 ++ptr를 합니다.

그로인해 ++ptr --> ptr = ptr + 1; ptr이 가르키는 곳이 다음 요소를 가르킵니다. ptr->n[2]이고 그 때 ptr이 가르키는 곳의 값을 찍기 때문에

*ptr은 n[2]의 를 가르키고 그곳의 값을 찍습니다.


Output    :    (    22        22    )


ptr -> n[2]

 0

 1

 2

 3

 4

5

 5

11->12

22 

34 

36 

44 



==========================================================================================


       7) printf("%d ", (*ptr)++);         printf(" %d\n", *ptr);


ptr을 기준으로 오른쪽이 없으니 왼쪽 *를 적용 따라서 ptr이 가르키는 곳의 값을 가지고 ++을 하는데 ++은 후처리이기 떄문에 printf함수가 끝나고 나서 적용됩니다. 따라서 printf로 찍힐 때는 ptr이 가르키는 곳의 값을 찍고 그 뒤에 (*ptr)++ -> *ptr = *ptr + 1; 

ptr이 가르키는 곳의 값을 + 1 증가 시킵니다.


Output    :    (    22        23    )


==========================================================================================



Total Output    :    

5         10

11        10

11        11

22        11

12        12

22        22

22        23




Output    :    

5         10

11        10

11        11

22        11

12        12

22        22

22        23

관련글 더보기

댓글 영역