Вход/Регистрация
Программирование. Принципы и практика использования C++ Исправленное издание
вернуться

Страуструп Бьерн

Шрифт:

class vector {

// ...

double& operator[](int n); // для неконстантных векторов

double operator[](int n) const; // для константных векторов

};

Очевидно, что мы не могли бы вернуть ссылку типа

double&
из версии со спецификатором
const
, поэтому возвращаем значение типа
double
. С таким же успехом мы могли бы вернуть ссылку типа
const double &
, но, поскольку объект типа
double
невелик, не имеет смысла возвращать ссылку (см. раздел 8.5.6), и мы решили вернуть значение. Теперь можно написать следующий код:

void ff(const vector& cv, vector& v)

{

double d = cv[1]; // отлично (использует константный вариант [ ])

cv[1] = 2.0; // ошибка (использует константный вариант [ ])

double d = v[1]; // отлично (использует неконстантный вариант [ ])

v[1] = 2.0; // отлично (использует неконстантный вариант [ ])

}

Поскольку объекты класса

vector
часто передаются по константной ссылке, эта версия оператора
operator[]
с ключевым словом
const
является существенным дополнением.

18.5. Массивы

До сих пор мы использовали слово массив (array) для названия последовательности объектов, расположенных в свободной памяти. Тем не менее массивы можно размещать где угодно как именованные переменные. На самом деле это распространенная ситуация. Они могут использоваться следующим образом.

• Как глобальные переменные (правда, использование глобальных переменных часто является плохой идеей).

• Как локальные переменные (однако массивы накладывают на них серьезные ограничения).

• Как аргументы функции (но массив не знает своего размера).

• Как член класса (хотя массивы, являющиеся членами класса, трудно инициализировать).

Возможно, вы заметили, что мы отдаем заметное предпочтение классу
vector
по сравнению с массивами. Класс
std::vector
следует использовать при любой возможности. Однако массивы существовали задолго до появления векторов и являлись их приблизительным прототипом во многих языках (особенно в языке C), поэтому их следует знать хорошо, чтобы иметь возможность работать со старыми программами или с программами, написанными людьми, не признающими преимущества класса
vector
.

Итак, что такое массив? Как его определить и как использовать? Массив — это однородная последовательность объектов, расположенных в смежных ячейках памяти; иначе говоря, все элементы массива имеют один и тот же тип, и между ними нет пробелов. Элементы массива нумеруются, начиная с нуля в возрастающем порядке. В объявлении массив выделяется квадратными скобками.

const int max = 100;

int gai[max]; // глобальный массив (из 100 чисел типа int);

// "живет всегда"

void f(int n)

{

char lac[20]; // локальный массив; "живет" до конца области

// видимости

int lai[60];

double lad[n]; // ошибка: размер массива не является константой

// ...

}

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

vector
с массивами элементов.

Как и к элементам массивов, размещенных в свободной области, доступ к элементам именованных массивов осуществляется с помощью операторов индексирования и разыменования (

[ ]
и
*
). Рассмотрим пример.

void f2

{

char lac[20]; // локальный массив; "живет" до конца области

// видимости

lac[7] = 'a';

*lac = 'b'; // эквивалент инструкции lac[0]='b'

lac[–2] = 'b'; // ??

lac[200] = 'c'; // ??

}

Эта функция компилируется, но, как мы знаем, не все скомпилированные функции работают правильно. Использование оператора
[ ]
очевидно, но проверка выхода за пределы допустимого диапазона отсутствует, поэтому функция
f2
компилируется, а результат записи
lac[–2]
и
lac[200]
приводит к катастрофе (как всегда, при выходе за пределы допустимого диапазона). Не делайте этого. Массивы не проверяют выход за пределы допустимого диапазона. И снова здесь нам приходится непосредственно работать с физической памятью, так как на системную поддержку рассчитывать не приходится.

  • Читать дальше
  • 1
  • ...
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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