Я полагаю, что мы все согласны с тем, что для доступа к истинному многомерному массиву считается разыменоваемым (возможно смещенным) указателем на его первый элемент одномерным способом, например:
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). Итак, очевидно, что undefined:
struct { int row[3]; // The object in question is an int[3] int other[10]; } foo; int *p = &foo.row[7]; // ERROR: A crude attempt to get &foo.other[4];
Таким образом, по тому же правилу можно ожидать, что следующее: undefined:
int mtx[5][3]; int (*row)[3] = &mtx[0]; // The object in question is still an int[3] int *p = &(*row)[7]; // Why is this any better?
Так почему это нужно определить?
int mtx[5][3]; int *p = &(&mtx[0][0])[7];
Итак, какая часть стандарта C явно разрешает это? (Предположим c99 ради обсуждения.)
ИЗМЕНИТЬ
Обратите внимание, что я не сомневаюсь, что это отлично работает во всех компиляторах. Я запрашиваю, разрешено ли это стандартным стандартом.