포인터 연산자의 경우 다른 연산자와 같이 사용되면, 정말 이해하기 힘들어집니다.
저도 이런 상황에서 항상 잘못 이해해서 오류를 만들곤 했습니다.
아래의 예는 사실 이렇게 혼란스럽게 사용하면 안 되지만, 일부로 공부를 위해 극단적인 예를
들어서 설명하려 합니다.
1 2 3 4 5 6 7 8 9 | int array[5] ={10, 20, 30, 40, 50}; int * p = array + 3; // array의 3번째 항목의 주소를 대입. 즉 {40, 50}
++*p++;
printf("%d \n", *p);
// 과연 다음의 값은 어떻게 될까요?
|
여기서 프린트 되는 값은 "50" 입니다.
이유를 설명하기 전에, 연산자 우선 순위에 대해 알고 있어야 합니다.
아래의 연산자 우선 순위(c언어 기준) 를 보면, '++(후위증가)' 연산자가 2 순위이며,
'++(전위증가)'와 '*' 우회(역참조)연산자가3순위입니다.
즉 2 순위를 먼저 해석해야 하며, 2 순위의 경우 … 결합 법칙상 왼쪽먼저
해석을 진행합니다. 그러나 p의 왼쪽엔 후위증가 연산자가 없으므로,
P의 오른쪽의 후위증가 연산자를 해석합니다.
그러면, ++*p++ 을 해석의 순서대로 나눠 보면…
++*p++ // 1. ++ 후위 증가를 한다.
++*p++ // 2. p++라는 값이 후위 증가가 된다. p는 {40, 50}을 가르키는 포인터이므로,
포인터 값이 증가된다면, { 50 } 을 가리키게 됩니다. 다만…. 후위 증가이므로, 현재라인에서는
변화가 없고, 아래 print문에서 변경사항이 적용됩니다.
// 3. 이제 나머지 3순위 연산자를 해석해봅니다. 3순위의 경우 오른쪽에서 왼쪽으로 해석합니다.
++*p++ // 3. *p …p가 가르키는 값이므로, { 40 }이 됩니다. 이 값을 ++ 전위 증가를 합니다.
그러면, 40은 1이 증가됩니다. (포인터의 주소값이 증가되는 것이 아니라, 그 값이… 증가됨)
그러므로, 41이 됩니다.
코드에 주석으로 각 라인마다 결과를 보면 아래와 같게 됩니다.
1 2 3 4 5 6 7 | int array[5] ={10, 20, 30, 40, 50}; int * p = array + 3; // array의 3번째 항목의 주소를 대입. 즉 {40, 50}
++*p++; // p는 {41, 50}
printf("%d \n", *p); // p는 { 50 } , array[5]는 { 10, 20, 30, 41, 50}
|
역시나 그래도 어렵고 복잡하긴 한데,
연산자 우선 순위를 이해하는 것을 공부하기에 좋은 문제 인 듯합니다. ^^
< 출처 : wiki https://ko.wikipedia.org/wiki/C%EC%99%80_C%2B%2B%EC%97%90%EC%84%9C%EC%9D%98_%EC%97%B0%EC%82%B0%EC%9E%90 >