Читаем Программирование. Принципы и практика использования C++ Исправленное издание полностью

Массив (array) — это последовательность, в которой доступ к каждому элементу осуществляется с помощью его индекса (позиции). Синонимом этого понятия является вектор (vector). В этом разделе мы уделим внимание многомерным массивам, элементами которых являются тоже массивы. Обычно многомерный массив называют матрицей (matrix). Разнообразие синонимов свидетельствует о популярности и полезности этого общего понятия. Стандартные классы vector (см. раздел Б.4), array (см. раздел 20.9), а также встроенный массив (см. раздел A.8.2) являются одномерными. А что если нам нужен двумерный массив (например, матрица)? А если нам нужны семь измерений? Проиллюстрировать одно- и двухмерные массивы можно так.

Массивы имеют фундаментальное значение в большинстве вычислений, связанных с так называемым “перемалыванием чисел” (“number crunching”). Наиболее интересные научные, технические, статистические и финансовые вычисления тесно связаны с массивами.

  Часто говорят, что массив состоит из строки столбцов.

Столбец — это последовательность элементов, имеющих одинаковые первые координаты (х-координаты). Строка — это множество элементов, имеющих одинаковые вторые координаты (y-координаты).

<p id="AutBody_Root465"><strong>24.4. Многомерные массивы в стиле языка С</strong></p>

В качестве многомерного массива можно использовать встроенный массив в языке С++ . В этом случае многомерный массив интерпретируется как массив массивов, т.е. массив, элементами которого являются массивы. Рассмотрим пример.

int ai[4];        // 1-мерный массив

double ad[3][4];  // 2-мерный массив

char ac[3][4][5]; // 3-мерный массив

ai[1] = 7;

ad[2][3] = 7.2;

ac[2][3][4] = 'c';

  Этот подход наследует все преимущества и недостатки одномерного массива.

• Преимущества

• Непосредственное отображение с помощью аппаратного обеспечения.

• Эффективные низкоуровневые операции.

• Непосредственная языковая поддержка.

• Проблемы

• Многомерные массивы в стиле языка являются массивами массивов(см. ниже).

• Фиксированные размеры (например, фиксированные на этапе компиляции). Если хотите определять размер массива на этапе выполнения программы, то должны использовать свободную память.

• Массивы невозможно передать аккуратно. Массив превращается в указатель на свой первый элемент при малейшей возможности.

• Нет проверки диапазона. Как обычно, массив не знает своего размера.

• Нет операций над массивами, даже присваивания (копирования).

Встроенные массивы широко используются в числовых расчетах. Они также являются основным источником ошибок и сложностей. Создание и отладка таких программ у большинства людей вызывают головную боль. Если вы вынуждены использовать встроенные массивы, почитайте учебники (например, The C++ Programming Language, Appendix C, p. 836–840). К сожалению, язык C++ унаследовал многомерные массивы от языка C, поэтому они до сих пор используются во многих программах.

  Большинство фундаментальных проблем заключается в том, что передать многомерные массивы аккуратно невозможно, поэтому приходится работать с указателями и выполнять явные вычисления, связанные с определением позиций в многомерном массиве. Рассмотрим пример.

void f1(int a[3][5]);     // имеет смысл только в матрице [3][5]

void f2(int [ ][5], int dim1);  // первая размерность может быть

                                // переменной

void f3(int [5 ][ ], int dim2); // ошибка: вторая размерность

                                // не может быть переменной

void f4(int[ ][ ], int dim1, int dim2); // ошибка (совсем

                                        // не работает)

void f5(int* m, int dim1, int dim2) // странно, но работает

{

  for (int i=0; i

  for (int j = 0; j

}

Здесь мы передаем массив m как указатель int*, даже если он является двумерным. Поскольку вторая переменная должна быть переменной (параметром), у нас нет никакой возможности сообщить компилятору, что массив m является массивом (dim1, dim2), поэтому мы просто передаем указатель на первую его ячейку. Выражение m[i*dim2+j] на самом деле означает m[i,j], но, поскольку компилятор не знает, что переменная m — это двумерный массив, мы должны сначала вычислить позицию элемента m[i,j] в памяти.

Этот способ слишком сложен, примитивен и уязвим для ошибок. Он также слишком медленный, поскольку явное вычисление позиции элемента усложняет оптимизацию. Вместо того чтобы учить вас, как справиться с этой ситуацией, мы сконцентрируемся на библиотеке С++, которая вообще устраняет проблемы, связанные с встроенными массивами.

<p id="AutBody_Root466"><strong>24.5. Библиотека Matrix</strong></p>
Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже