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

Matrix a(3,4);

int s = a.size();  // количество элементов

int d1 = a.dim1(); // количество элементов в строке

int d2 = a.dim2(); // количество элементов в столбце

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

                   // языка С

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

Мы можем использовать индексы.

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

         // диапазона

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

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

  В двумерном объекте класса Matrix индексирование с помощью конструкции [i] создает одномерный объект класса Matrix, представляющий собой i-ю строку. Это значит, что мы можем извлекать строки и передавать их операторам и функциям, получающим в качестве аргументов одномерные объекты класса Matrix и даже встроенные массивы (a[i].data()). Обратите внимание на то, что индексирование вида a(i,j) может оказаться быстрее, чем индексирование вида a[i][j], хотя это сильно зависит от компилятора и оптимизатора.

Мы можем получить срезки.

a.slice(i);   // строки от a[i] до последней

a.slice(i,n); // строки от a[i] до a[i+n–1]

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

Matrix a2 = a; // копирующая инициализация

a = a2;          // копирующее присваивание

a *= 7;          // пересчет (и +=, –=, /= и т.д.)

a.apply(f);      // a(i,j)=f(a(i,j)) для каждого элемента a(i,j)

a.apply(f,7);    // a(i,j)=f(a(i,j),7) для каждого элемента a(i,j)

b=apply(f,a);    // создаем новую матрицу с b(i,j)==f(a(i,j))

b=apply(f,a,7);  // создаем новую матрицу с b(i,j)==f(a(i,j),7)

Оказывается, что перестановка строк также полезна, поэтому мы предусмотрим и ее.

a.swap_rows(1,2); // перестановка строк a[1] <–> a[2]

  Перестановки столбцов swap_columns() не существует. Если она вам потребуется, то вы сможете написать ее самостоятельно (см. упр. 11). Из-за построчной схемы хранения матриц в памяти строки и столбцы не совсем равноправны. Эта асимметрия проявляется также в том, что оператор [i] возвращает только строку (а для столбцов аналогичный оператор не предусмотрен). Итак, в тройке (i,j) первый индекс i выбирает строку. Эта асимметрия имеет глубокие математические корни.

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

enum Piece { none, pawn, knight, queen, king, bishop, rook };

Matrix board(8,8); // шахматная доска

const int white_start_row = 0;

const int black_start_row = 7;

Piece init_pos[] = {rook,knight,bishop, queen,king,bishop,knight,rook};

Matrix start_row(init_pos); // инициализация элементов из

                                   // init_pos

Matrix clear_row(8);        // 8 элементов со значениями

                                   // по умолчанию

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

Matrix start_row = {rook,knight,bishop,queen,king,bishop,knight,rook};

Перейти на страницу:

Похожие книги

Programming with POSIX® Threads
Programming with POSIX® Threads

With this practical book, you will attain a solid understanding of threads and will discover how to put this powerful mode of programming to work in real-world applications. The primary advantage of threaded programming is that it enables your applications to accomplish more than one task at the same time by using the number-crunching power of multiprocessor parallelism and by automatically exploiting I/O concurrency in your code, even on a single processor machine. The result: applications that are faster, more responsive to users, and often easier to maintain. Threaded programming is particularly well suited to network programming where it helps alleviate the bottleneck of slow network I/O. This book offers an in-depth description of the IEEE operating system interface standard, POSIX (Portable Operating System Interface) threads, commonly called Pthreads. Written for experienced C programmers, but assuming no previous knowledge of threads, the book explains basic concepts such as asynchronous programming, the lifecycle of a thread, and synchronization. You then move to more advanced topics such as attributes objects, thread-specific data, and realtime scheduling. An entire chapter is devoted to "real code," with a look at barriers, read/write locks, the work queue manager, and how to utilize existing libraries. In addition, the book tackles one of the thorniest problems faced by thread programmers-debugging-with valuable suggestions on how to avoid code errors and performance problems from the outset. Numerous annotated examples are used to illustrate real-world concepts. A Pthreads mini-reference and a look at future standardization are also included.

David Butenhof

Программирование, программы, базы данных