Программирование. Принципы и практика использования C++ Исправленное издание, стр. 333
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<dim1; ++i) for (int j = 0; j<dim2; ++j) m[i*dim2+j] = 0;}Здесь мы передаем массив
mint*mdim1, dim2m[i*dim2+j]m[i,j]mm[i,j]Этот способ слишком сложен, примитивен и уязвим для ошибок. Он также слишком медленный, поскольку явное вычисление позиции элемента усложняет оптимизацию. Вместо того чтобы учить вас, как справиться с этой ситуацией, мы сконцентрируемся на библиотеке С++, которая вообще устраняет проблемы, связанные с встроенными массивами.
24.5. Библиотека Matrix
• “Мой код должен выглядеть очень похожим на описание массивов, изложенное в большинстве учебников по математике”.
• Это относится также к векторам, матрицам и тензорам.
• Проверка на этапах компиляции и выполнения программы.
• Массивы любой размерности.
• Массивы с произвольным количеством элементов в любой размерности.
• Массивы являются полноценными переменными/объектами.
• Их можно передавать куда угодно.
• Обычные операции над массивами.
• Индексирование:
()• Срезка:
[]• Присваивание:
=• Операции пересчета (
+=–=*=%=• Встроенные векторные операции (например,
res[i] = a[i]*c+b[2]• Скалярное произведение (res = сумма элементов
a[i]*b[i]inner_product• По существу, обеспечивает автоматическое преобразование традиционного исчисления массивов/векторов в текст программы, который в противном случае вы должны были бы написать сами (и добиться, чтобы они были не менее эффективными).
• Массивы при необходимости можно увеличивать (при их реализации не используются “магические” числа).
Библиотека
MatrixMatrixMatrixMatrix.hNumeric_libMatrixMatrix24.5.1. Размерности и доступ
Рассмотрим простой пример.
#include "Matrix.h"using namespace Numeric_lib;void f(int n1, int n2, int n3){