숏컷 코드
포인터 산술은 바이트 계산보다 원소 이동으로 읽는 편이 맞습니다. ptr + 1은 “한 칸 다음 원소”를 뜻하고, 배열 인덱싱도 결국 같은 규칙 위에 서 있습니다.
int data[] = {10, 20, 30, 40, 50};
int *ptr = data;
printf("%d\n", *ptr);
printf("%d\n", *(ptr + 1));
ptr++;문법
포인터 산술은 pointer + integer, pointer - integer, pointer - pointer 정도가 핵심입니다. 중요한 건 “몇 바이트”가 아니라 현재 포인터 타입의 원소 크기만큼 움직인다는 점입니다.
int data[] = {10, 20, 30, 40};
int *p = data;
printf("%d\n", *p); // 10
printf("%d\n", *(p + 2)); // 30배열 인덱싱도 같은 규칙입니다. arr[i]는 결국 *(arr + i)를 더 읽기 쉽게 쓴 문법입니다.
int arr[] = {3, 6, 9};
printf("%d\n", arr[1]);
printf("%d\n", *(arr + 1));문법
포인터끼리 빼는 연산은 “주소 차이”가 아니라 같은 배열 객체 안에서 몇 칸 차이 나는지를 구하는 연산입니다. 결과 타입은 ptrdiff_t입니다.
int arr[] = {10, 20, 30, 40, 50};
int *start = &arr[1];
int *end = &arr[4];
ptrdiff_t count = end - start; // 3arr + n처럼 마지막 원소 바로 다음 위치를 가리키는 포인터는 순회 경계 비교에는 자주 씁니다. 하지만 그 위치를 역참조하면 안 됩니다.
ptr + 1은 바이트 1이 아니라 원소 1칸 이동이다.arr[i]와*(arr + i)는 같은 뜻이다.end - start는 같은 배열 안 원소 거리 계산이다.- 마지막 다음 위치는 비교에는 쓸 수 있어도 읽거나 쓰면 안 된다.
- 다른 배열이나 다른 객체 사이 포인터 산술은 정의되지 않는다.
주의할 점
포인터 산술은 같은 배열 객체 범위 안에서만 유효합니다. 마지막 원소 다음 위치는 비교에는 쓸 수 있어도 역참조는 안 됩니다.
int arr[5] = {0};
int *p = arr + 5;
// ❌ 역참조 금지
*p = 99;참고 링크
1 sources