Чтение онлайн

на главную - закладки

Жанры

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

ad1 = ai; // ошибка: разные типы элементов

ad1 = ad11; // исключение Matrix_error

// (разные размерности)

Matrix<double,2> ad2(n1); // ошибка: пропущена длина 2-й

// размерности

ad2(3) = 7.5; // ошибка: неправильное количество

// индексов

ad2(1,2,3) = 7.5; // ошибка: неправильное количество

// индексов

Matrix<double,3> ad3(n1,n2,n3);

Matrix<double,3> ad33(n1,n2,n3);

ad3 = ad33; // OK:
одинаковые типы элементов,

// одинаковые размерности

}

Несоответствия между объявленным количеством размерностей и их использованием обнаруживается на этапе компиляции. Выход за пределы диапазона перехватывается на этапе выполнения программы; при этом генерируется исключение

Matrix_error
.

Первая размерность матрицы — это строка, а вторая — столбец, поэтому индекс — это двумерная матрица (двумерный массив), имеющая вид (строка,столбец). Можно также использовать обозначение [строка][столбец], так как индексирование двумерной матрицы с помощью одномерного индекса порождает одномерную матрицу — строку. Эту ситуацию можно проиллюстрировать следующим образом.

Этот объект класса

Matrix
размещается в памяти построчно.

Класс

Matrix
знает свою размерность, поэтому его элементы можно очень просто передавать как аргумент,

void init(Matrix<int,2>& a) // инициализация каждого элемента

// характеристическим значением

{

for (int i=0; i<a.dim1; ++i)

for (int j = 0; j<a.dim2; ++j)

a(i,j) = 10*i+j;

}

void print(const Matrix<int,2>& a) // вывод элементов построчно

{

for (int i=0; i<a.dim1; ++i) {

for (int j = 0; j<a.dim2; ++j)

cout << a(i,j) <<'\t';

cout << '\n';

}

}

Итак,
dim1
— это количество элементов в первой размерности,
dim2
— количество элементов во второй размерности и т.д. Тип элементов и количество размерностей являются частью класса
Matrix
, поэтому невозможно написать функцию, получающую объект класса
Matrix
как аргумент (но
можно написать шаблон).

void init(Matrix& a); // ошибка: пропущены тип элементов

// и количество размерностей

Обратите внимание на то, что библиотека

Matrix
не содержит матричных операций, например, сложение двух четырехмерных матриц или умножение двумерных матриц с одномерными. Элегантная реализация этих операций выходит за рамки этой библиотеки. Соответствующие матричные библиотеки можно надстроить над библиотекой
Matrix
(см. упр. 12).

24.5.2. Одномерный объект класса Matrix

Что можно сделать с простейшим объектом класса

Matrix
— одномерной матрицей?

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

Matrix<int,1> a1(8); // a1 — это одномерная матрица целых чисел

Matrix<int> a(8); // т.е. Matrix<int,1> a(8);

Таким образом, объекты

a
и
a1
имеют одинаковый тип (
Matrix<int,1>
). У каждого объекта класса
Matrix
можно запросить общее количество элементов и количество элементов в определенном измерении. У одномерного объекта класса
Matrix
эти параметры совпадают.

a.size; // количество элементов в объекте класса Matrix

a.dim1; // количество элементов в первом измерении

Можно также обращаться к элементам матрицы, используя схему их размещения в памяти, т.е. через указатель на ее первый элемент.

int* p = a.data; // извлекаем данные с помощью указателя на массив

Это полезно при передаче объектов класса

Matrix
функциям в стиле языка C, принимающим указатели в качестве аргументов. Матрицы можно индексировать.

a(i); // i-й элемент (в стиле языка Fortran) с проверкой

// диапазона

a[i]; // i-й элемент (в стиле языка C) с проверкой диапазона

a(1,2); // ошибка: a — одномерный объект класса Matrix

Многие алгоритмы обращаются к части объекта класса

Matrix
. Эта часть называется срезкой и создается функцией
slice
(часть объекта класса
Matrix
или диапазон элементов). В классе
Matrix
есть два варианта этой функции.

a.slice(i); // элементы, начиная с a[i] и заканчивая последним

a.slice(i,n); // n элементов, начиная с a[i] и заканчивая a[i+n–1]

Индексы и срезки можно использовать как в левой части оператора присваивания, так и в правой. Они ссылаются на элементы объекта класса

Matrix
, не создавая их копии. Рассмотрим пример.

a.slice(4,4) = a.slice(0,4); // присваиваем первую половину матрицы

Поделиться:
Популярные книги

Мастер Разума V

Кронос Александр
5. Мастер Разума
Фантастика:
городское фэнтези
попаданцы
5.00
рейтинг книги
Мастер Разума V

Последний из рода Демидовых

Ветров Борис
Фантастика:
детективная фантастика
попаданцы
аниме
5.00
рейтинг книги
Последний из рода Демидовых

Любовь Носорога

Зайцева Мария
Любовные романы:
современные любовные романы
9.11
рейтинг книги
Любовь Носорога

Авиатор: назад в СССР 12

Дорин Михаил
12. Покоряя небо
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Авиатор: назад в СССР 12

Толян и его команда

Иванов Дмитрий
6. Девяностые
Фантастика:
попаданцы
альтернативная история
7.17
рейтинг книги
Толян и его команда

Академия

Кондакова Анна
2. Клан Волка
Фантастика:
боевая фантастика
5.40
рейтинг книги
Академия

Изгой. Пенталогия

Михайлов Дем Алексеевич
Изгой
Фантастика:
фэнтези
9.01
рейтинг книги
Изгой. Пенталогия

Неудержимый. Книга IX

Боярский Андрей
9. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга IX

Невеста

Вудворт Франциска
Любовные романы:
любовно-фантастические романы
эро литература
8.54
рейтинг книги
Невеста

Энфис 2

Кронос Александр
2. Эрра
Фантастика:
героическая фантастика
рпг
аниме
5.00
рейтинг книги
Энфис 2

Убийца

Бубела Олег Николаевич
3. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.26
рейтинг книги
Убийца

Лорд Системы

Токсик Саша
1. Лорд Системы
Фантастика:
фэнтези
попаданцы
рпг
4.00
рейтинг книги
Лорд Системы

Делегат

Астахов Евгений Евгеньевич
6. Сопряжение
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Делегат

Невеста напрокат

Завгородняя Анна Александровна
Любовные романы:
любовно-фантастические романы
6.20
рейтинг книги
Невеста напрокат