본문 바로가기
Language&Framework&Etc/C

포인터와 배열! 함께 이해하기(13-2) 포인터 연산

by 머리올리자 2020. 12. 8.

포인터를 대상으로 메모리의 접근을 위한 * 이외에 증가 및 감소연산도 가능하다.

중요한 것은 증가 및 감소연산이 가능하다는 사실이 아님 → 중요한 것은 연산의 결과

 

포인터를 대상으로 하는 증가 및 감소연산

포인터 변수를 대상으로 다음과 같이 증가 및 감소 연산 진행 가능

 

예제

#include <stdio.h>

int main(void)
{
	int* ptr1 = 0x0010;
	double* ptr2 = 0x0010;

	printf("ptr1 = %p\n", ptr1);
	printf("ptr1+1 = %p\n", ptr1+1); // 4 증가
	printf("ptr1+2 = %p\n", ptr1+2); // 8 증가

	printf("ptr2 = %p\n", ptr2);
	printf("ptr2+1 = %p\n", ptr2 + 1); // 8 증가
	printf("ptr2+2 = %p\n", ptr2 + 2); // 16 증가


	ptr1++;
	ptr2++;

	printf("ptr1 = %p\n", ptr1);
	printf("ptr2 = %p\n", ptr2);


	return 0;
}

적절한 초기화는 아니지만 연산 예시를 위해 진행

 

위 결과를 통해 알 수 있는 것

 

"int형 포인터를 대상으로 1을 증가시키면 4가 증가하고 double형 포인터를 대상으로 1을 증가시키면 8이 증가 한다"

 

int형 포인터를 대상으로 n 증가(or 감소) n x sizeof(int)의 크기만큼 증가(or 감소)
double형 포인터를 대상으로 n 증가(or 감소) n x sizeof(double)의 크기만큼 증가

"TYPE형 포인터를 대상으로 n의 크기만큼 값을 증가 및 감소 시, n x sizeof(TYPE)의 크기만큼 주소 값이 증가 및 감소한다"

 

포인터 연산 특성으로 배열 접근이 가능

#include <stdio.h>

int main(void)
{
	int arr[3] = { 11, 22, 33 };
	int* ptr = arr; // int* ptr = &arr[0]; 과 같은 문장
	printf("%d %d %d \n", *ptr, *(ptr + 1), *(ptr + 2));

	printf("%d ", *ptr); ptr++; // printf 함수호출 후, ptr++ 실행
	printf("%d ", *ptr); ptr++;
	printf("%d ", *ptr); ptr--; // printf 함수호출 후, ptr-- 실행
	printf("%d ", *ptr); ptr--;
	printf("%d ", *ptr); printf("\n");


	return 0;
}

선언된 포인터 변수 ptr은 int형 포인터이므로 값을 1 증가시키는 연산을 할 때마다 실제로는 4가 증가한다.

따라서 배열 arr이 할당된 위치의 주소 값을 0x001000 이라 가정할 떄, (ptr+1)과 (ptr+2)의 연산결과로 반환되는 주소 값이 가리키는 위치는 아래와 같다

때문에 *ptr, *(ptr+1), *(ptr+2)의 참조결과 출력 시 arr[0], arr[1], arr[2]에 저장된 요소가 출력된 것

 

ptr++ 및 ptr--는 포인터 변수 ptr에 저장된 값을 증가 및 감소시키는 연산을 진행하고 있다.

이 결과로 포인터 변수 ptr에 저장된 값은 4씩 증가 및 감소가 이뤄지기 때문에 포인터 변수 ptr이 가리키는 위치는 다음과 같이 변경

 

 

차이점 비교

1. *(++ptr) = 20;

2. *(ptr+1) = 20;

 

두 문장 모두 현재 ptr이 가리키는 위치에서 4바이트 떨어진 메모리 공간에 20을 저장하는 문장

하지만 연산이후 포인터 변수 ptr의 상태에는 차이가 있음

 

1.의 경우 ++ 연산의 결과로 포인터 변수 ptr에 저장된 값이 4만큼 증가한다.

2.의 경우 + 연산으로 인해서는 ptr에 저장된 값이 증가하지 않는다.

 

결론

위 코드에서 *ptr, *(ptr + 1), *(ptr + 2) 출력 결과는 arr[0], arr[1], arr[2]의 출력 결과와 동일함을 확인

ptr에 저장된 값이 arr의 주소 값이기 때문에 다음 네 문장은 사실상 같은 것이며 동일한 출력

 

#include <stdio.h>

int main(void)
{
	int arr[3] = { 11, 22, 33 };
	int* ptr = arr;
	printf("%d %d %d \n", *(ptr+0), *(ptr + 1), *(ptr + 2));
	printf("%d %d %d \n", ptr[0], ptr[1], ptr[2]);
	printf("%d %d %d \n", *(arr + 0), *(arr + 1), *(arr + 2));
	printf("%d %d %d \n", arr[0], arr[1], arr[2]);

	return 0;
}

"arr[i] == *(arr+1)"

 

 

참고 : [윤성우 열혈 C 프로그래밍] - 대부분의 내용 및 코드는 이 책에서 개인 공부 정리 목적으로 참고하였습니다.