Я полагаю, мы все согласны с тем, что 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]
?Обычно индексирование конца массива (кроме одного конца) не определено (C99, 6.5.6/8). Таким образом, следующее явно не определено:
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];
Таким образом, по тому же правилу можно было бы ожидать, что следующее будет неопределенным:
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.)
ИЗМЕНИТЬ
Обратите внимание, что я не сомневаюсь, что это прекрасно работает во всех компиляторах. Я спрашиваю, разрешено ли это явно стандартом.
[][]
, такая же, как и для*(array + x * index + y)
. - person RedX   schedule 09.06.2011arr + 1 * 5 * sizeof(arrType) + 5 * sizeof (arrType)
... - person Wouter Simons   schedule 09.06.2011mtx
на самом деле являетсяint[5][3]
, но распадается наint(*)[3]
. - person Oliver Charlesworth   schedule 09.06.2011