Computer >> 컴퓨터 >  >> 프로그래밍 >> C 프로그래밍

C/C++ 배열에서 a[i] == i[a]가 성립하는 이유

C/C++에는 의외로 많은 개발자가 모르는 흥미로운 특징이 있습니다. 바로 배열 첨자 표기법에서 a[i]i[a]처럼 뒤집어 쓸 수도 있다는 점입니다. 얼핏 보면 문법 오류처럼 보이지만, 실제로는 아무 문제 없이 컴파일되며 완전히 동일한 결과를 출력합니다.

왜 이런 일이 가능할까요?

그 비밀은 C/C++ 표준의 배열 첨자 연산 정의에 숨어 있습니다. C/C++에서 E1[E2]는 항상 다음과 같이 정의됩니다.

E1[E2] → *((E1) + (E2))

즉, 컴파일러는 내부적으로 포인터 산술(pointer arithmetic)을 수행하여 배열 요소에 접근합니다. 여기에 이항 + 연산자에 적용되는 형 변환 규칙이 더해집니다. E1이 배열 객체이고 E2가 정수라면, E1[E2]는 배열 E1의 E2번째 요소를 의미하게 됩니다.

핵심은 덧셈은 교환 법칙이 성립한다는 점입니다. 따라서 다음 두 식은 완전히 동일합니다.

a[i] = *(a + i)
i[a] = *(i + a)

포인터 산술 관점에서 (a + i)(i + a)는 같은 메모리 주소를 가리키므로, 결국 a[i]i[a]는 본질적으로 같은 표현식인 셈입니다.

예제 코드

#include <iostream>
using namespace std;
int main() {
   int array[] = {1, 2, 3, 4, 5, 6, 7};
   cout << "array[5] is " << array[5] << endl;
   cout << "5[array] is " << 5[array];
}

실행 결과

array[5] is 6
5[array] is 6

정리

배열 첨자 연산은 문법적 설탕(syntactic sugar)일 뿐, 실제로는 포인터와 오프셋의 덧셈으로 변환됩니다. 덧셈의 교환 법칙 때문에 피연산자의 순서를 바꿔도 결과가 달라지지 않으며, 그래서 a[i]i[a]가 같은 값이 되는 것입니다. 물론 실무 코드에서는 가독성을 위해 반드시 a[i] 형태로 작성하는 것이 좋습니다.