О тождестве говорю не я, а стандрат языка С. Был бы у меня под рукой K&R первого издания - я бы и на него ссылку привёл. Никакой вспомогательный массив не нужен (кстати, векторизация многомерного массива - это действительно имеющая смысл ручная оптимизация, но это изменение сути программы, оптимизация на уровне алгориима, а не жонглирования операторами).
int x[LEN1][LEN2]; // зона памяти LEN1*LEN2*sizeof(int)
x - это массив из LEN1 массивов по LEN2 int-ов
x[i] - это i-тый подмассив, по смыслу - указатель на первый его элемент.
По определению оператора индексации []
x[i] <=> *(x+i)
и тут ещё нет никакого
дополнительного указателя
(x[i])[j] - это j-тый элемент того подмассива.
Опять по определению
x[i][j] <=> *(x[i]+j) <=> *(*(x+i)+j)
Подчёркиваю - не "так себя обычно ведут компиляторы", а это то, как стандарт объявил - что именно
означают квадратные скобки в языке С. Т.е. это то, что компилятор
обязан делать внутри себя квадратные скобки обрабатывать.
Далее ему позволяется при оптимизации делать какие-то "улучшения", которые не меняют результат, т.е. которые приводят к тому же результату, который будет при рассмотрении x[i][j] как *(x[i]+j) <=> *(*(x+i)+j)