플로렌스라는 개발자

프로그래밍/C 2019.04.17 댓글 0 Plorence

포인터 연산

포인터 연산

포인터 연산이란 말그대로 포인터를 대상으로 하는 연산입니다.
*연산자를 사용할경우에는 포인터가 지시하고 있는 메모리공간에 접근하여 연산합니다.
연산자는 +=,-=,++,--,*,/ 등 모든 연산자를 사용할 수 있습니다.

int * ptr;
ptr = ptr + 1;

ptr+1을 하게되면 포인터 변수 ptr이 가리키는 대상이 아닌 포인터 변수 ptr에 저장되어있는 주소값자체를 1 올려줍니다.
근데 여기서 특이한 점이 있습니다. 실제로는 진짜 1이 아니고 포인터형 타입의 사이즈만큼 올려줍니다.
즉 2를 올려준다면 '포인터형의 사이즈 * 2'값을 주소값에서 더해주는겁니다.
int 형 포인터 변수 ptr가 000004를 가지고 있고 ptr + 1해준다면
포인터 변수 ptr는 000008을 가지게 됩니다.

sizeof(ptr) * N //N만큼 증가할때 실제 증가하는 계산식

*(++ptr)와 *(ptr+1)의 차이점

++ptr는 연산의 결과로 인해서 ptr에 저장된 값이 4증가합니다.
하지만 *(ptr+1)는 ptr에 저장된값이 4로 증가되지 않고 증가된값을 연산의 결과로 얻어서 *연산을 진행합니다.
순서를 따져보자면 *(++ptr)은 ptr에다가 1을더하고 저장된값을 가지고 *연산을 진행합니다. 

(영구적,즉 저장된 값 자체를 변경)
*(ptr+1)은 ptr에다가 1을 더한값을 저장하지않고 그값을 +연산의결과로 가져와서 *연산을 진행합니다. 

(1회성, 즉 저장된값은 변경되지 않음)

 

이로인해 한가지 알 수 있는 사실

배열 원소에 접근할때 쓰는 []연산자도 사실은 내부에서는 *연산자를 사용합니다.

그로인해 배열의 원소에 접근할때 포인터를 통한 *연산으로도 가능합니다.

#include <stdio.h>
int main (void){
    int arr[] = {1,2,3};
    int * ptr = arr;
    printf("%d,%d,%d \n",arr[0],arr[1],arr[2]); //1,2,3 출력
    printf("%d,%d,%d \n",*(ptr+0),*(ptr+1),*(ptr+2)); //1,2,3 출력
    printf("%d,%d,%d \n",*(arr+0),*(arr+1),*(arr+2)); //1,2,3 출력
    return 0;
    
}

여기서 내릴수있는 중요한 결론은 arr[i] == * (arr+i)

arr는 포인터 변수도 성립하고 배열의 이름도 성립합니다.
다만 상수형태의 포인터라서 *(++arr)같은 연산은 컴파일 에러가 발생합니다.