Читаем Программирование полностью

// ...

Обратите внимание на уродливую конструкцию, используемую для доступа к данным Джилл: (*jill_data)[i]. Функция get_from_jill() возвращает указатель на вектор, а именно vector*. Для того чтобы получить данные, мы сначала должны его разыменовать, получив доступ к вектору с помощью указателя *jill_ data, а затем применить к нему операцию индексирования. Однако выражение *jill_data[i] — не совсем то, что мы хотели; оно означает *(jill_data[i]), так как оператор [] имеет более высокий приоритет, чем *, поэтому нам необходимы скобки вокруг конструкции *jill_data, т.е. выражение (*jill_data)[i].

ПОПРОБУЙТЕ

Как вы изменили бы интерфейс, чтобы избежать неуклюжих конструкций, если бы могли изменить код Джилл?

<p id="AutBody_Root372"><strong>20.1.2. Обобщение кода</strong></p>

  Нам нужен единообразный способ доступа и манипуляции данными, чтобы не переписывать программу каждый раз, когда представление данных немного изменяется. Посмотрим на коды Джека и Джилл и попробуем сделать их более абстрактными и единообразными.

Разумеется, все, что мы сделаем с данными Джека, относится и к данным Джилл. Однако между их программами есть два досадных различия: переменные jack_count и jill_data–>size(), а также конструкции jack_data[i] и (*jill_data)[i]. Последнее различие можно устранить, введя ссылку.

vector& v = *jill_data;

for (int i=0; i

  if (h

  {

    jill_high = &v[i];

    h = v[i];

  }

Это очень похоже на код для обработки данных Джека. Может быть, стоит написать функцию, которая выполняла бы вычисления как с данными Джилл, так и с данными Джека? Возможны разные пути (см. упр. 3), но, стремясь к более высокой степени обобщения кода (см. следующие две главы), мы выбрали решение, основанное на указателях.

double* high(double* first, double* last)

// возвращает указатель на наибольший элемент в диапазоне [first,last]

{

  double h = –1;

  double* high;

  for(double* p = first; p!=last; ++p)

    if (h<*p)

    {

      high = p;

      h = *p;

    }

  return high;

}

Теперь можно написать следующий код:

double* jack_high = high(jack_data,jack_data+jack_count);

vector& v = *jill_data;

double* jill_high = high(&v[0],&v[0]+v.size());

Он выглядит получше. Мы не ввели слишком много переменных и написали только один цикл (в функции high()). Если мы хотим найти наибольший элемент, то можем посмотреть на значения *jack_high и *jill_high. Рассмотрим пример.

cout << "Максимум Джилл: " << *jill_high

     << "; максимум Джека: " << *jack_high;

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

ПОПРОБУЙТЕ

В этой маленькой программе мы оставили две потенциально опасные ошибки. Одна из них может вызвать катастрофу, а другая приводит к неправильным ответам, если функция high() будет использоваться в других программах. Универсальный прием, который описывается ниже, выявит обе эти ошибки и покажет, как их устранить. Пока просто найдите их и предложите свои способы их исправления.

Функция high() решает одну конкретную задачу, поэтому она ограничена следующими условиями.

• Она работает только с массивами. Мы считаем, что элементы объекта класса vector хранятся в массиве, но наряду с этим существует множество способов хранения данных, таких как списки и ассоциативные массивы (см. разделы 20.4 и 21.6.1).

• Ее можно применять только к объектам класса vector и массивам типа double, но не к векторам и массивам с другими типами элементов, например vector и char[10].

• Она находит элемент с максимальным значением, но с этими данными можно выполнить множество других простых вычислений.

Попробуем обеспечить более высокую общность вычислений над нашими наборами данных.

Обратите внимание на то, что, решив выразить алгоритм поиска наибольшего элемента в терминах указателей, мы “случайно” уже обобщили решение задачи: при желании мы можем найти наибольший элемент массива или вектора, но, помимо этого, можем найти максимальный элемент части массива или вектора. Рассмотрим пример.

// ...

vector& v = *jill_data;

double* middle = &v[0]+v.size()/2;

double* high1 = high(&v[0], middle);          // максимум первой

                                              // половины

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

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

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

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