Язык С++ и программирование на нем. Рейзлин В.И. - 37 стр.

UptoLike

Составители: 

39
Если инициализируется многомерный массив, то самую первую
размерность можно не задавать. В этом случае компилятор сам вычис-
ляет размер массива:
int f [ ][2] = { 2, 4, 6, 1 }; // массив f [2][2];
int a [ ][2][2] = { 1, 2, 3, 4, 5, 6, 7, 8 }; // массив a [2][2][2].
Инициализирующее выражение может иметь вид, отражающий
факт, что массив является, например, двумерным:
int c[2][3]={ {1, 7}, {-5, 3} };
В этом случае в матрице c инициализированы нулевой и первой
столбцы, а второй столбец, то есть элементы c[0][2] и c[1][2], ини-
циализируется нулями.
5.6. Указатели и многомерные массивы
Рассмотрим разницу между объектами a и b, описанными сле-
дующим образом:
int a[10][10];
int * b[10];
И a и b можно использовать сходным образом в том смысле, что
как a[5][5], так и b[5][5] являются обращениями к отдельному значению
типа int. Но a настоящий массив: под него отводится 100 ячеек памя-
ти и для нахождения любого указанного элемента проводятся обычные
вычисления с индексами, которые требуют умножения. Для b описание
выделяет только 10 указателей. Каждый из них должен быть установлен
так, чтобы он указывал на массив целых.
Если предположить, что каждый из них указывает на массив из 10
элементов, то тогда где-то будет отведено 100 ячеек памяти плюс еще
10 ячеек для указателей. Таким образом, массив указателей использует
несколько больший объем памяти и может требовать наличие явного
шага инициализации. Но при этом возникают 2 преимущества: доступ к
элементу осуществляется косвенно через указатель, а не посредством
умножения и сложения, и строки массива могут иметь различные дли-
ны. Это означает, что каждый элемент b не должен обязательно указы-
вать на вектор из 10 элементов. Эту разницу можно увидеть в следую-
щем примере: