2015년 5월 6일 수요일

C/C++언어의 포인터 연산

 먼저 다음 예제를 살펴보자

#include <stdio.h>
int main()
{
   short sa=10, sb=11, *spa=&sa, *spb=&sb;
   long la=20, lb=21, *lpa=&la, *lpb=&lb;
   printf("%p, %p\n", spa, spb);
   printf("%p, %p\n", lpa, lpb);
}

printf()함수에서 %p 형식지정자는 포인터를 출력할 때 사용되며 주소를 16진수로 표시해준다. 실행 결과는 다음과 같다. (주소는 PC마다 다를 수 있다.)

ffffff12, ffffff10
0028ff0c, 0028ff08

변수 sa와 sb는 인접한 메모리에 저장되는데 주소값의 차이가 2가 난다. short형이 2바이트 자료형이기 때문이다. 마찬가지로 long형은 4바이트 자료형이므로 인접한  la와 lb는 주소가 4가 차이가 난다.

 C++ 에서 포인터에 정수를 더하거나 빼기도 하고 포인터끼리 뺄셈을 하는 등 연산 기능을 제공한다. 이러한 연산을 통해 포인터가 가리키는 주소를 변화시키거나 포인터들이 가리키는 주소 간 거리를 계산할 수 있다. 이러한 기능은 특히 배열을 다룰 때 유용하게 사용된다.

 포인터에 정수를 더하거나 뺄 수 있는데 이 경우 (주소의) 변량은  다음과 같다.

  • 더하거나 빼는 정수×데이터형의 크기

다음 예를 보자.

#include <stdio.h>
int main()
{
   short sa = 10;
   short *spa = &sa;
   printf("%p\n", spa++);
   printf("%p\n", spa);
   printf("%p\n", spa+2);
}

실행결과는 다음과 같다.(주소값은 PC마다 다를 수 있다.)

0028ff1a
0028ff1c
0028ff20

포인터 spa를 1 증가시켰는데 주소값은 2가 증가되었다. 이는 spa가 short형 포인터이고 short는 2바이트를 차지하는 자료형이기 때문이다. 그리고 spa+2는 주소값이 4가 증가되었는데 (정수)*(바이트수) 만큼 증가되기 때문이다.

 증감연산자와 포인터 연산자를 조합한 몇 가지 혼동할 여지가 있는 예를 들어보자.

*(++ipA)  // 포인터값을 먼저 증가시킨 해당 변수의 값을 참조
*(ipA++)  // 해당 변수값을 참조한 다음 포인터값을 증가
++(*ipA)  // *ipA 변수값 1 증가후 그 값 참조
(*ipA)++  // *ipA 값 참조 후 변수값 1 증가

이 예제들의 경우 괄호를 생략하여 가독성을 떨어뜨리는 것은 바람직하지 않다.


댓글 없음:

댓글 쓰기