Я полагаю, мы все согласны с тем, что это считается идиоматическим C для доступа к истинному многомерному массиву путем разыменования (возможно, смещения) указателя на его первый элемент одномерным способом, например:
void clearBottomRightElement(int *array, int M, int N)
{
array[M*N-1] = 0; // Pretend the array is one-dimensional
}
int mtx[5][3];
...
clearBottomRightElement(&mtx[0][0], 5, 3);
Однако языковой юрист во мне нуждается в убеждении, что это на самом деле четко определенный C! В частности:
Гарантирует ли стандарт, что компилятор не будет вставлять отступы между ними, например mtx [0] [2]
и mtx [1] [0]
?
Обычно индексация с конца массива (кроме одного за концом) выполняется undefined (C99, 6.5.6 / 8). Таким образом, следующее явно не определено:
struct {
int row [3]; // Рассматриваемый объект - это int [3]
int other [10];
} foo;
int * p = & foo.row [7]; // ОШИБКА: грубая попытка получить & foo.other [4];
Таким образом, по тому же правилу можно ожидать, что следующее будет неопределенным:
int mtx [5] [3];
int (* строка) [3] = & mtx [0]; // Рассматриваемый объект по-прежнему является int [3]
int * p = & (* строка) [7]; // Почему это лучше?
Так почему это должно быть определено?
int mtx [5] [3];
int * p = & (& mtx [0] [0]) [7];
Так какая часть стандарта C явно разрешает это? (Давайте предположим c99 для обсуждения.)
РЕДАКТИРОВАТЬ
Обратите внимание, что я не сомневаюсь, что это отлично работает во всех компиляторах. Я спрашиваю, разрешено ли это явно стандартом.