다른 답변에서 무언가를 놓치고 있다고 생각합니다.
그렇습니다. p[i]
정의는이며 *(p+i)
, 덧셈은 덧셈이되므로 *(i+p)
이며, []
연산자 의 정의에 따라 동일합니다 i[p]
.
(에서 array[i]
배열 이름은 암시 적으로 배열의 첫 번째 요소에 대한 포인터로 변환됩니다.)
그러나 더하기의 commutativity가이 경우에 명백한 것은 아닙니다.
두 피연산자가 같은 유형이거나 공통 유형으로 승격 된 다른 숫자 유형 인 경우, commutativity는 다음과 같이 완벽하게 이해 x + y == y + x
됩니다.
그러나이 경우 포인터 연산에 대해 구체적으로 이야기하고 있습니다. 한 피연산자는 포인터이고 다른 피연산자는 정수입니다. (정수 + 정수는 다른 연산이며 포인터 + 포인터는 의미가 없습니다.)
C 표준의 +
연산자 ( N1570 6.5.6)에 대한 설명 은 다음과 같습니다.
또한 두 피연산자 모두 산술 유형을 갖거나 한 피연산자는 완전한 객체 유형에 대한 포인터이고 다른 피연산자는 정수 유형이어야합니다.
그것은 쉽게 말할 수 있습니다 :
또한 두 피연산자 모두 산술 유형을 가지거나 왼쪽
피연산자는 완전한 객체 유형에 대한 포인터이고 오른쪽 피연산자
는 정수 유형이어야합니다.
이 경우 모두 i + p
와 i[p]
불법이 될 것입니다.
C ++ 용어로, 우리는 실제로 +
다음과 같이 느슨하게 설명 될 수있는 두 세트의 오버로드 연산자를 가지고 있습니다.
pointer operator+(pointer p, integer i);
과
pointer operator+(integer i, pointer p);
그중 첫 번째 만이 실제로 필요합니다.
왜 이런 식입니까?
C ++은 B (배열 인덱스의 교환 법칙이 명시 1972에서 설명한에서있어 C에서이 정의 유전 B에 대한 사용자의 참조 에서있어) BCPL 아니라 짝수로를 받고있다 (수동 일자 1967), 이전 언어 (CPL? Algol?).
따라서 배열 인덱싱은 덧셈의 관점에서 정의되고, 포인터와 정수의 덧셈도 계산적이며 수십 년 전 C의 조상 언어로 거슬러 올라갑니다.
이 언어들은 현대 C보다 훨씬 덜 타이핑되었습니다. 특히, 포인터와 정수의 구별은 종종 무시되었습니다. (초기 C 프로그래머들은 unsigned
키워드를 언어에 추가 하기 전에 포인터를 부호없는 정수로 사용하기도했습니다 .) 따라서 피연산자가 다른 유형이기 때문에 비정규 식을 추가하는 아이디어는 해당 언어의 디자이너에게는 발생하지 않았을 것입니다. 사용자가 정수, 포인터 또는 그 밖의 다른 것을 포함하여 두 개의 "사물"을 추가하고자한다면 언어에 의존하지 않았습니다.
그리고 수년에 걸쳐이 규칙을 변경하면 기존 코드가 손상되었을 수 있습니다 (1989 ANSI C 표준이 좋은 기회 였을 수도 있음).
포인터를 왼쪽에 놓고 정수를 오른쪽에 놓도록 C 및 / 또는 C ++를 변경하면 일부 기존 코드가 손상 될 수 있지만 실제 표현력이 손실되지는 않습니다.
그래서 지금 우리가 arr[3]
하고 3[arr]
후자의 형태가 바깥에 표시해서는 안하지만, 정확히 같은 일을 의미 IOCCC .