본문 바로가기

프로그래밍/C언어

[C언어] 포인터(5) - 포인터의 연산

안녕하세요 ! 초보개발자 입니다. 

이 블로그는 개인 공부 정리용 블로그 입니다. 

혹 잘못된 내용이 있다면 지적 부탁드리겠습니다.

그리고 질문주신다면 최대한 아는선에서 답변드리도록 하겠습니다.

그럼 시작하도록 하겠습니다.




1.포인터(5)


1) 포인터의 연산


포인터에 저장된 값은 부호없는 정수 입니다. 그렇기 때문에 정수 처럼 덧셈 뺄셈 등 증감연산자나 비교연산도 가능합니다. 


다음과 같은 코드에서 ptr++의 결과를 알아 보도록 하겠습니다.


int *ptr = (int *)0x100; 


ptr++을 하였으니 0x101될 것이라고 생각할 수 있습니다. 하지만 이것은 잘못된 생각 입니다. ptr은 int 형이기 때문에 0x100 ~ 0x103 까지의 범위를 사용합니다. 그렇기 때문에 ptr++을 했을 경우에는 0x104임을 알 수 있습니다. 위의 내용을 예제를 통해 알아 보겠습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<stdio.h>
int main(void) {
 
    char* pc = (char*)0x100;
    int* pi = (int*)0x100;
 
    printf("sizeof(char) = %d\n"sizeof(char));
    printf("sizeof(int) = %d\n"sizeof(int));
    printf("pc++ =0x%x \t pi++=0x%x\n", pc++, pi++);
    printf("pc++ =0x%x \t pi++=0x%x\n", pc++, pi++);
    printf("pc++ =0x%x \t pi++=0x%x\n", pc++, pi++);
    printf("pc++ =0x%x \t pi++=0x%x\n", pc++, pi++);
    printf("pc++ =0x%x \t pi++=0x%x\n", pc++, pi++);
    return 0;
}
 
cs


결과는 아래와 같이 출력 됩니다.

 sizeof(char) = 1

 sizeof(int) = 4

 pc++ =0x100      pi++=0x100

 pc++ =0x101      pi++=0x104

 pc++ =0x102      pi++=0x108

 pc++ =0x103      pi++=0x10c

 pc++ =0x104      pi++=0x110

포인터가 가리키는 타입의 크기만큼 증가한다는 것을 알 수 있습니다.


아래의 예제도 한번 살펴 보겠습니다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<stdio.h>
int main(void) {
 
    int arr[] = { 0,1,2,3,4 };
    int* ptr = &arr[0];
 
    int arrLength = sizeof(arr) / sizeof(arr[0]);
 
    for (int i = 0; i < arrLength; i++) {
        printf("ptr++ = %p, &arr[%d] = %p\n", ptr++, i, &arr[i]);
    }
    printf("\n");
    ptr = &arr[0];
    for (int i = 0; i < arrLength; i++) {
        printf("*ptr++=%d, arr[%d]=%d\n"*ptr++, i, arr[i]);
    }
 
    return 0;
}
 
cs


실행결과는 다음과 같습니다.

 ptr++ = 0077FAD8, &arr[0] = 0077FAD8

 ptr++ = 0077FADC, &arr[1] = 0077FADC

 ptr++ = 0077FAE0, &arr[2] = 0077FAE0

 ptr++ = 0077FAE4, &arr[3] = 0077FAE4

 ptr++ =  0077FAE8, &arr[4] = 0077FAE8


 *ptr++=0, arr[0]=0

 *ptr++=1, arr[1]=1

 *ptr++=2, arr[2]=2

 *ptr++=3, arr[3]=3

 *ptr++=4, arr[4]=4


*ptr++ 은 *(ptr++)과 같으며 ptr이 가리키는 값을 가져온 후에 ptr이 증가한다는 뜻입니다. 

2) 포인터의 덧셈과 뺄셈

포인터의 덧셈은 위에서 배운것 처럼 포인터가 가리키는 타입에 따라 다르게 변합니다. 예를 들어 int* ptr 에 정수 3을 더하면 실제로는 포인터의 값에 3*sizeof(*ptr)를 더한 것과 같습니다.

포인터의 뺄셈에 대해 알아 보겠습니다. 만약 다음과 같은 코드에서 결과값을 예상해보라고 하면 어떻게 나올까요 ?

int arr[4];

                      int diff = &arr[2]-&arr[0]; 

주소값의 차이는 8이니까 8이 나올 것을 예상할 수 있습니다. 하지만 정답은 2가 나옵니다. diff가 int 형이기 때문입니다. 포인터의 뺄셈은 같은 타입만 가능하기 때문에 양쪽 모두 같은 타입으로 바꿔주어야 합니다. 예제를 통해서 덧셈과 뺄셈을 살펴 보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<stdio.h>
int main(void) {
 
    int arr[4];
    int* ptr = (int*)0x100;
 
    printf("ptr-3 = %p\n", ptr - 3);
    printf("ptr-2 = %p\n", ptr - 2);
    printf("ptr-1 = %p\n", ptr - 1);
    printf("ptr+0 = %p\n", ptr);
    printf("ptr+1 = %p\n", ptr+1);
    printf("ptr+2 = %p\n", ptr+2);
    printf("ptr+3 = %p\n", ptr+3);
 
    return 0;
}
cs

실행 결과는 다음과 같습니다.

ptr-3 = 000000F4

ptr-2 = 000000F8

ptr-1 = 000000FC

ptr+0 = 00000100

ptr+1 = 00000104

ptr+2 = 00000108

ptr+3 = 0000010C


3) 포인터의 비교 연산 

포인터의 비교 연산으로 두포인터의 값이 같은지 또는 다른지 그리고 어느 포인터가 큰지 작은지 확인을 할 수 있습니다.

예제를 통해서 알아 보겠습니다. 

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
30
31
32
33
34
35
36
37
#include<stdio.h>
int main(void) {
 
    int arr[4= { 0,1,2,3 };
    int* ptr = &arr[0];
    int* ptr2 =&arr[1];
    printf("ptr의 값을 ptr2로 복사하기전\n");
    printf("ptr = %p\n", ptr);
    printf("ptr2 = %p\n", ptr2);
 
    if (ptr == ptr2) {
        printf("ptr과 ptr2는 같은 값입니다.\n");
 
    }
    else {
        printf("ptr과 ptr2는 다른 값입니다.\n");
    }
 
 
    printf("\n");
    printf("ptr의 값을 ptr2로 복사한 후\n");
    ptr2 = ptr;
    
    printf("ptr = %p\n", ptr);
    printf("ptr2 = %p\n", ptr2);
 
    if (ptr == ptr2) {
        printf("ptr과 ptr2는 같은 값입니다.\n");
 
    }
    else {
        printf("ptr과 ptr2는 다른 값입니다.\n");
    }
 
    return 0;
}
 
cs

다음은 실행 결과 입니다.

ptr의 값을 ptr2로 복사하기전

ptr = 00F6FB58

ptr2 = 00F6FB5C

ptr과 ptr2는 다른 값입니다.


ptr의 값을 ptr2로 복사한 후

ptr = 00F6FB58

ptr2 = 00F6FB58

ptr과 ptr2는 같은 값입니다. 


이번 예제는 소스만으로도 이해 하실 수 있을 것입니다. 오늘의 강의는 여기서 마치도록 하겠습니다. 다음시간에도 이어서 포인터에 대해서 알아 보겠습니다.