Иногда я вижу разные стили доступа к массиву в C ++ и думаю, что это может быть связано с режимом адресации сборки:
C ++:
int * aa=new int[2];
0[aa]=15; //a little different than aa[0]
1[aa]=15;
aa[0]=15;
aa[1]=15;
printf("%d %d \n",aa[0],aa[1]);
Монтаж:
__asm
{
mov aa[0],ebx
mov aa[1],eax
mov 0[aa],ebx
mov 1[aa],eax
}
Является ли эта нотация доступа к массиву C ++ стандартом и, если да, была ли она получена из режима адресации сборки?
Когда я пытаюсь [aa]1=5;
Компилятор дает
msgstr «левый операнд должен быть l-значением».
// Когда я пытаюсь арифметику указателя,
* (aa + 1) = 0 // не дает ошибок
* (aa + 0) = 0 // не дает ошибок 🙂
Это правило одинаково для перегрузки оператора []?
MSVC ++ 2010
Спасибо.
Это хорошо известная причуда C и C ++, им все равно, какая половина выражения идет в квадратных скобках []
, Они оба оценивают одно и то же эквивалентное выражение:
*(0+aa)=15;
Выражение a[b]
по сути переводится на *(a+b)
,
Вот почему этот «стиль» 11[arr]
возможно.
Причина [aa]11
не является чисто синтаксическим.
Является ли эта нотация доступа к массиву C ++ стандартом?
Да. Пока один операнд является указателем, а другой арифметическим, a[b]
эквивалентно *(a+b)
, поэтому не имеет значения, находится ли указатель или индекс внутри []
,
если да, был ли он получен из режима адресации сборки?
Почти наверняка нет. Синтаксис взят непосредственно из C, который был первоначально разработан для семейства компьютеров PDP, где был написан этот режим адресации сборок. 1(aa)
,
Когда я пытаюсь
[aa]1=5
, компилятор выдает (ошибки)
Это потому, что синтаксис для выражения нижнего индекса указан как postfix-expression [ expression ]
так что операнд в []
должен прийти за другим.
Это правило одинаково для перегрузки оператора []?
Нет. Если оператор был перегружен, то a[b]
эквивалентно a.operator[](b)
, и не b.operator[](a)
,