Вход/Регистрация
Программирование. Принципы и практика использования 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); // присваиваем первую половину матрицы

// второй

Например, если объект a вначале выглядел так:

{ 1 2 3 4 5 6 7 8 }

то получим

{ 1 2 3 4 1 2 3 4 }

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

Matrix
; т.е.
a.slice(0,j)
— это диапазон
[0:j]
, а
a.slice(j)
— диапазон
[j:a.size]
. В частности, приведенный выше пример можно легко переписать:

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

// второй

Иначе говоря, обозначения — дело вкуса. Вы можете указать такие индексы

i
и
n
, так что
a.slice(i,n)
выйдет за пределы диапазона матрицы
a
. Однако полученная срезка будет содержать только те элементы, которые действительно принадлежат объекту
a
. Например, срезка
a.slice(i,a.size)
означает диапазон
[i:a.size]
, а
a.slice(a.size)
и
a.slice(a.size,2)
— это пустые объекты класса
Matrix
. Это оказывается полезным во многих алгоритмах. Мы подсмотрели это обозначение в математических текстах. Очевидно, что срезка
a.slice(i,0)
является пустым объектом класса
Matrix
. Нам не следовало бы писать это намеренно, но существуют алгоритмы, которые становятся проще, если срезка
a.slice(i,n)
при параметре
n
, равном
0
, является пустой матрицей (это позволяет избежать ошибки).

Копирование всех элементов выполняется как обычно.

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

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

К каждому элементу объекта класса
Matrix
можно применять встроенные операции.

a *= 7; // пересчет: a[i]*=7 для каждого i (кроме того, +=, –=, /=

// и т.д.)

a = 7; // a[i]=7 для каждого i

Это относится к каждому оператору присваивания и каждому составному оператору присваивания (

=
,
+=
,
–=
,
/=
,
*=
,
%=
,
^=
,
&=
,
|=
,
>>=
,
<<=
) при условии, что тип элемента поддерживает соответствующий оператор. Кроме того, к каждому элементу объекта класса
Matrix
можно применять функции.

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

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

Составные операторы присваивания и функция

apply
модифицируют свои аргументы типа
Matrix
. Если же мы захотим создать новый объект класса
Matrix
, то можем выполнить следующую инструкцию:

b = apply(abs,a); // создаем новый объект класса Matrix

// с условием b(i)==abs(a(i))

Функция

abs
— это стандартная функция вычисления абсолютной величины (раздел 24.8). По существу, функция
apply(f,x)
связана с функцией
x.apply(f)
точно так же, как оператор
+
связан с оператором
+=
. Рассмотрим пример.

b = a*7; // b[i] = a[i]*7 для каждого i

a *= 7; // a[i] = a[i]*7 для каждого i

y = apply(f,x); // y[i] = f(x[i]) для каждого i

  • Читать дальше
  • 1
  • ...
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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