Pointer Arithmetics in C의 한국어 번역

안녕하세요, 미래의 프로그래머 여러분! 오늘은 C 언어에서 포인터 항상식에 대해 흥미로운 여정을 떠날 거예요. 프로그래밍에 새로운 여러분도 걱정하지 마세요; 저는 여러분을 단계별로 안내해 드릴 거예요, 마치 저가 지난 몇 년간 수많은 학생들을 가르쳐 준 것처럼요. 그럼, 좋아하는 음료를 준비하고 편하게 앉아서 함께 빠져나가보죠!

C - Pointer Arithmetics

포인터란 무엇인가요?

포인터 항상식에 뛰어들기 전에, 빨리 포인터에 대해 정리해 보죠. C에서 포인터는 다른 변수의 메모리 주소를 저장하는 변수입니다. 컴퓨터의 메모리에 어떤 데이터가 저장되어 있는지 가리키는 문서와 같이 생각해 보세요.

단순한 예제를 보죠:

int x = 10;
int *ptr = &x;

이 코드에서 ptrx의 주소를 저장하는 포인터입니다. & 연산자는 x의 주소를 가져옵니다.

이제 기억을 새롭게 하였으니, 마법의 세계인 포인터 항상식을 탐험해 보죠!

포인터의 증가와 감소

일반 변수처럼 포인터도 증가하고 감소할 수 있습니다. 하지만 여기서 흥미로운 점이 있습니다: 포인터를 증가시키거나 감소시킬 때, 주소에 1을 추가하거나 뺄 것이 아니라, 포인터가 가리키는 데이터 타입의 다음이나 이전 요소로 이동합니다.

예를 들어보죠:

int arr[] = {10, 20, 30, 40, 50};
int *ptr = arr;  // ptr는 arr의 첫 번째 요소를 가리킵니다

printf("%d\n", *ptr);  // 출력: 10
ptr++;
printf("%d\n", *ptr);  // 출력: 20
ptr--;
printf("%d\n", *ptr);  // 출력: 10

이 코드에서 ptr를 증가시키면, 주소에 1을 추가하는 것이 아니라 배열의 다음 정수로 이동합니다. 마찬가지로 감소시키면 이전 정수로 이동합니다.

배열을 걷는 것과 같습니다. 증가나 감소의 각 단계는 메모리에 얼마나 많은 바이트를 占쏘는지에 관계없이 다음이나 이전 요소로 이동합니다.

포인터에 정수 추가 및 빼기

포인터에 정수를 추가하거나 빼る 수도 있습니다. 이 연산은 증가나 감소와 유사하지만, 한 번에 여러 단계로 이동할 수 있습니다.

예를 들어보죠:

int arr[] = {10, 20, 30, 40, 50};
int *ptr = arr;

printf("%d\n", *(ptr + 2));  // 출력: 30
printf("%d\n", *(ptr + 4));  // 출력: 50
printf("%d\n", *(ptr - 1));  // 정의되지 않은 행동! 주의하세요!

ptr에 2를 추가하면, 주소에 2를 추가하는 것이 아니라 배열의 2 정수 앞으로 이동합니다. 마찬가지로 ptr + 4는 4 정수 앞으로 이동합니다.

하지만 주의하세요! 배열의 시작 전에 메모리에 접근하려고 시도하면 (ptr가 배열의 시작位置일 때 ptr - 1), 정의되지 않은 행동을 얻게 됩니다. 책의 첫 페이지에 있을 때 이전 페이지를 읽으려고 시도하는 것과 같습니다 – 그런 페이지는 존재하지 않습니다!

포인터의 빼기

좋은 방법을 알려드릴게요: 하나의 포인터에서 다른 포인터를 빼면, 두 포인터 사이의 요소 수를 알 수 있습니다. 이는 두 포인터가 동일한 배열의 요소를 가리킬 때만 작동합니다.

예를 보죠:

int arr[] = {10, 20, 30, 40, 50};
int *ptr1 = arr;
int *ptr2 = &arr[3];

printf("%ld\n", ptr2 - ptr1);  // 출력: 3
printf("%ld\n", ptr1 - ptr2);  // 출력: -3

이 코드에서 ptr2 - ptr1arr[0]arr[3] 사이에 3 개의 요소가ある 이유로 3을 반환합니다. 주의하세요, 결과는 부호가 붙어 있습니다 – 더 큰 포인터에서 더 작은 포인터를 뺄 때 음수가 반환됩니다.

포인터의 비교

마지막으로, 관계 연산자(<, >, <=, >=, ==, !=)를 사용하여 포인터를 비교할 수 있습니다. 이는 특히 배열을 작업할 때 유용합니다.

예를 들어보죠:

int arr[] = {10, 20, 30, 40, 50};
int *ptr1 = arr;
int *ptr2 = &arr[3];

if (ptr1 < ptr2) {
    printf("ptr1은 ptr2가 가리키는 요소보다 앞에 있는 요소를 가리킵니다\n");
}

if (ptr1 == &arr[0]) {
    printf("ptr1은 배열의 첫 번째 요소를 가리킵니다\n");
}

이 코드에서는 ptr1ptr2가 가리키는 요소의 위치를 비교합니다. 기억하세요, 포인터를 비교할 때는 실제로 메모리 주소를 비교하고 있습니다.

포인터 항상식 연산 요약

핸들러 테이블로 포인터 항상식 연산을 요약해 보죠:

연산 설명 예제
증가(++) 다음 요소로 이동 ptr++
감소(--) 이전 요소로 이동 ptr--
추가(+) n 개의 요소 앞으로 이동 ptr + n
빼기(-) n 개의 요소 뒤로 이동 ptr - n
포인터 빼기 포인터 사이의 요소 계산 ptr2 - ptr1
비교 요소의 위치 비교 ptr1 < ptr2

그리고 그렇게 끝납니다! C에서 포인터 항상식의 땅을 거쳤습니다. 위대한 힘은 위대한 책임과 함께 옵니다. 포인터 항상식은 강력한 도구지만, 신중하게 사용하지 않으면 버그를 일으킬 수 있습니다. 항상 접근하지 말아야 할 메모리에 접근하지 않도록 주의하세요!

항상 학생들에게 말하는 것처럼, 이 개념을 정말 이해하려면 연습하는 것이 최선입니다. 그럼 C 컴파일러를 켜고 이 연산을 실험해 보세요. 코딩 잘하시고, 포인터가 항상 여러분이 원하는 곳을 가리키길 바랍니다!

Credits: Image by storyset