본문 바로가기

BackEnd/C

제한된 형태의 포인터 연산

반응형


1. 포인터를 가지고 덧셈과 뺄셈이 가능


포인터 연산이라는 것은 포인터를 피연산자로 하는 연산 전부를 의미한다.


대표적인 포인터관련 연산자는 다음과 같다.


*     메모리참조

&    주소 값 반환


그리고 포인터의 덧셈과 뺄셈이 있는데 일반적인 것과는 의미가 다르다. 예제를 보자


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

#include <stdio.h>
 
int main(void)
{
    int num1=10;
    double num2=7.12345;
 
    int * ptr1=&num1;
    double * ptr2=&num2;
 
    printf("ptr1: %d \n", ptr1);
    printf("ptr2: %d \n\n", ptr2);
 
    ptr1++, ptr2++;
    printf("ptr1: %d \n", ptr1);
    printf("ptr2: %d \n\n", ptr2);
 
    printf("ptr1: %d \n", ptr1+3);
    printf("ptr2: %d \n\n", ptr2+3);
 
    ptr1--, ptr2--;
    printf("ptr1: %d \n", ptr1);
    printf("ptr2: %d \n\n", ptr2);
 
    printf("ptr1: %d \n", ptr1-3);
    printf("ptr2: %d \n\n", ptr2-3);
 
    return 0;
}
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
ptr1: 6487612
ptr2: 6487600
 
ptr1: 6487616
ptr2: 6487608
 
ptr1: 6487628
ptr2: 6487632
 
ptr1: 6487612
ptr2: 6487600
 
ptr1: 6487600
ptr2: 6487576
cs


14행에서 선언한 포인터 변수의 값을 1씩 증가시키는 연산을 하고 있다. 


그런데 값이 일반 변수와 달리 4와 8이 증가되었다.


이 예제를 통해 int형 포인터 변수의 값을 1증가시키면 int 형 변수의 크기인 4가 증가된다.


dobule형 포인터 변수의 값을 1증가시, double형 변수의 크기인 8이 증가된다.


즉 type형 포인터 변수의 값을 1증가 및 감소시키면, sizeof(type)의 크기만큼 증가 및 감소한다.


2. 포인터 연산을 통한 배열 요소 접근


포인터 값의 증가 및 감소는 배열에 접근할때 쓰일 수 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

#include <stdio.h>
 
int main(void)
{
    int arr[]={12345};
    int * ptr=&arr[2];
    printf("현 위치: %d \n\n"*ptr);
 
    printf("한 칸 앞: %d \n"*(ptr+1));
    printf("두 칸 앞: %d \n\n"*(ptr+2));
 
    printf("한 칸 뒤: %d \n"*(ptr-1));
    printf("두 칸 뒤: %d \n\n"*(ptr-2));
 
    return 0;
}

cs


1
2
3
4
5
6
7
현 위치: 3
 
한 칸 앞: 4
두 칸 앞: 5
 
한 칸 뒤: 2
두 칸 뒤: 1
cs


6행에서 배열 arr의 세번째 요소의 주소값을 얻고 있다.


9행에서 포인터 ptr에 1을 더하여 *연산을 하고 있다. 


이때 주소 값은 4가 증가 되므로 ptr가 가리키는 배열 요소의 다음 번째 배열 요소의 값을 출력한다.


3. 포인터 변수의 값이 1씩 증가 및 감소하지 않는 이유


위 예제를 보았는데 값이 1씩 증가 및 감소하면 배열 요소의 값을 제대로 출력 못할것이다.


포인터는 데이터의 첫 번째 바이트를 가리키는 녀석이다. 


따라서 첫 번째 바이트를 기준으로 데이터의 참조를 위한 *연산도 이뤄진다. 


그래서 포인터가 int형 변수의 중간을 가리키면 데이터 참조를 위한 *연산의 결과가 무의미해진다.



위 그림의 ptr은 int형 포인터이다. 처음 ptr은 4의 첫번째 바이트를 가리켰다고 해보자.


그리고 +2 연산후에 포인터는 숫자 4가 저장되어 있는 변수의 중간을 가리킨다고 해보자.


이렇게 되면 *연산을 할경우 숫자4와 5가 저장된 두 변수의 뒤와 앞을 2바이트씩 참조하여 엉뚱한 


값을 반환한다. 그래서 포인터 변수의 값을 1증가시키면 int 형 변수의 크기인 4가 증가되는 것이다.


다른 예제 하나 더 봐보자


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

#include <stdio.h>
 
int main(void)
{
    int arr[]={12345};
    int * ptr=arr;    // int * ptr=&arr[0];
 
    printf("1번째 요소: %d \n"*(ptr++));
    printf("2번째 요소: %d \n"*(ptr++));
    printf("3번째 요소: %d \n"*(ptr++));
    printf("4번째 요소: %d \n"*(ptr++));
    printf("5번째 요소: %d \n"*(ptr));
 
    return 0;
}
cs


1
2
3
4
5
1번째 요소: 1
2번째 요소: 2
3번째 요소: 3
4번째 요소: 4
5번째 요소: 5
cs

여기서도 마찬가지로 8행부터 보면 ++연산자는 포인터 ptr에 저장된 값을 sizeof(int)의 반환 값만


큼 증가시켜 배열에 접근한다.

반응형

'BackEnd > C' 카테고리의 다른 글

다차원 배열 이름의 포인터형  (0) 2019.03.14
배열의 이름은 상수 형태의 포인터이다.  (0) 2019.03.13
포인터 배열  (0) 2019.03.13
포인터의 포인터  (0) 2019.03.13
문자열 배열과 문자열을 참조하는 포인터  (0) 2019.03.12