배열의 포인터 연산
앞의 배열에 관한 내용을 조금 복습하자면, 배열의 이름은 상수형 포인터라고 했다.
그렇다면, *연산이 가능할까? 정답은 Yes이다.
다음 예제를 살펴보자.
#include <stdio.h>
int main () {
int arr_i[3] = {1,2,3};
double arr_d[3] = {1.1, 2.2, 3.3};
printf("%d %g\n", *arr_i, *arr_d);
*arr_i += 10;
*arr_d += 120.5;
printf("%d %g\n", arr_i[0], arr_d[0]);
}
실행 결과
1 1.1
11 121.6
포인터의 *연산이 무리없이 작동하는 것을 알 수 있다.
포인터를 배열의 이름처럼
배열이름이 포인터이고 포인터처럼 사용할 수 있다면, 포인터를 배열처럼 사용할 수 있을까?
두개의 예제를 보자. 첫번째 예제는 책에서 나온 예제를 살짝 바꾼 것이고, 두번째 예제는 내가 생각해낸 방법이다.
// 1
#include <stdio.h>
int main () {
int arr[3] = {1,2,3};
int * ptr = arr;
for (int i = 0; i < 3; i++) {
printf("%d %d\n", ptr[i], arr[i]);
}
}
실행 결과
1 1
2 2
3 3
// 2
#include <stdio.h>
#include <stdlib.h>
int main () {
int *ptr = malloc(sizeof(int) * 3);
for (int i = 0; i < 3; i++) {
ptr[i] = i+1;
}
for (int i = 0; i < 3; i++) {
printf("%d\n", ptr[i]);
}
free(ptr);
}
실행 결과
1
2
3
결론은 포인터를 배열의 이름처럼 사용할 수 있다. 하지만 책의 필자는 배열을 포인터처럼 쓰거나 포인터를 배열의 이름으로 사용하는 일은 거의 없다고 한다. (솔직히 공부중인 내가 봐도 그래보인다) 하지만 이러한 일이 가능하다는 사실, 그리고 이론은 알고 있어야 한다고 한다.
포인터의 증감 연산
지금까지 배운 포인터와 관련된 연산은 *연산과 &연산이 있다. 하지만 포인터는 증감연산 또한 가능하다.
예제를 보도록 하자.
#include <stdio.h>
int main () {
int a = 1; // 안전한 메모리 접근을 위해 변수를 선언한다.
double b = 1.1;
int *ptr1 = &a;
double *ptr2 = &b;
printf("size of int: %d, size of double : %d\n\n", sizeof(int), sizeof(double));
printf("origin --> ptr1 : %p, ptr2 : %p \n", ptr1, ptr2);
printf("ptr1 --> %p %p \n", ptr1+1, ptr1+2);
printf("ptr2 --> %p %p \n\n", ptr2+1, ptr2+2);
printf("before : %p %p \n", ptr1++, ptr2++);
printf("after : %p %p", ptr1, ptr2);
}
실행 결과
size of int: 4, size of double: 8
origin --> ptr1 : 0061FF14, ptr2 : 0061FF08
ptr1 --> 0061FF18 0061FF1C
ptr2 --> 0061FF10 0061FF18
before : 0061FF14 0061FF08
after : 0061FF18 0061FF10
int형 포인터에 각각 1과 2를 더했더니, 1과 2 자체가 더해지는 것이 아니라 각각 4와 8이 더해지는것을 알 수 있다.
마찬가지로 double형 포인터는 8과 16이 더해짐을 알 수 있다.
이를 통해 알 수 있는 것은 TYPE 형 포인터에 n만큼 증감연산을 시도하면, 그 값은 n * sizeof(TYPE)만큼 변한다는 것을 알 수 있다.
이를 응용하면, 배열에서도 사용할 수 있다.
#include <stdio.h>
int main () {
int arr[] = {1,2,3};
int *ptr = arr;
printf("%d ", *(ptr++));
printf("%d ", *(ptr++));
printf("%d ", *(ptr--));
printf("%d ", *(ptr--));
printf("%d ", *ptr);
return 0;
}
실행 결과
1 2 3 2 1
즉, arr[i] = *(arr + i)이라는 결론이 나온다.
정리할게 더 남아있지만, 일정이 있어 부득이하게 중간에서 끊고, 다음 정리에서 이어서 써야겠다. 내용이 섞이게 되어 안타깝다....