Почему это работает? Доступ к нелогичному массиву
Возможный дубликат:
В массивах C почему это так? a [5] == 5 [a]
Мой друг изучает С++ в первый раз и отправил мне этот фрагмент:
int foo[] = { 3, 38, 38, 0, 19, 21, 3, 11, 19, 42 };
char bar[] = " abcdefghijklmnopqrstuvwxyz01234567890+-,.!?-_";
for (int i = 0; i < 10; ++i) {
std::cout << foo[i][bar];
}
С первого взгляда я сказал ему, что это не сработает - я думал, что он не будет компилироваться или, по крайней мере, приведет к нарушению доступа, поскольку foo
не является двумерным массивом, к которому он ответил, что это так.
Я пробовал для себя, и, к моему удивлению, фрагмент прошел отлично. Вопрос: почему?
Согласно логике, здравому смыслу и хорошей практике, синтаксис должен быть bar[foo[i]]
.
Мне стыдно признаться, что я понятия не имею, что происходит. Что делает foo[i][bar]
допустимым синтаксисом в этом случае?
Ответы
Ответ 1
В упрощенном виде доступ элемента массива в C (и в С++, когда []
не перегружен) выглядит следующим образом:
x[i] = *(x + i)
Итак, с этим и немного арифметикой...
foo[i][bar]
= (foo[i])[bar]
= (*(foo + i))[bar]
= *((*(foo + i)) + bar)
= *(bar + (*(foo + i)))
= bar[*(foo + i)]
= bar[foo[i]]
Не используйте этот "факт". Как вы видели, это делает код нечитаемым, а нечитаемый код недостижим.