Я думаю, що в інших відповідях щось не вистачає.
Так, p[i]
за визначенням еквівалентний *(p+i)
, що (оскільки додавання є комутативним) еквівалентно *(i+p)
, що (знову ж таки, за визначенням []
оператора) еквівалентно i[p]
.
(І в тому array[i]
, ім'я масиву неявно перетворюється на вказівник на перший елемент масиву.)
Але комутативність додавання не все так очевидно в даному випадку.
Коли обидва операнда мають значення того ж типу, або навіть різних числових типів, які сприяли до загального типу, коммутативности має сенс: 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 ++ усвідомив це визначення від C, яке отримало його від B (комутативність індексації масивів чітко згадується у Посиланні користувачів 1972 року на B ), яка отримала його від BCPL (керівництво від 1967 р.), Яке , можливо, отримало його навіть від більш ранні мови (CPL? Algol?).
Отже, ідея про те, що індексація масиву визначена в термінах додавання, і що додавання, навіть вказівник і ціле число, є комутативним, йде багато десятиліть на мови предків С.
Ці мови були набагато менш сильно набрані, ніж сучасна мова С. Зокрема, різницю між вказівниками та цілими числами часто ігнорували. (Програмісти раннього С іноді використовували вказівники як цілі числа без підпису, перш ніж unsigned
ключове слово було додано до мови.) Отже, ідея зробити додавання некомутативним, оскільки операнди різного типу, ймовірно, не виникли б у дизайнерів цих мов. Якщо користувач хотів додати дві "речі", будь то ці "цілі", цілі числа, покажчики чи щось інше, мова не могла запобігти.
І з роками будь-яка зміна цього правила порушила б існуючий код (хоча стандарт ANSI C 1989 р. Міг бути гарною можливістю).
Змінюючи C та / або C ++, щоб вимагати введення вказівника зліва та цілого числа справа може порушити деякий існуючий код, але реальної виразної сили не буде втрачено.
Отже, ми маємо arr[3]
і маємо на 3[arr]
увазі саме те саме, хоча остання форма ніколи не повинна з’являтися поза МОККЦ .