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

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

Шрифт:

// возвращает указатель на наибольший элемент в диапазоне [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<double>& 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<double*>
и
char[10]
.

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

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

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

// ...

vector<double>& v = *jill_data;

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

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

// половины

double* high2 = high(middle, &v[0]+v.size); // максимум второй

// половины

// ...

Здесь указатель

high1
ссылается на максимальный элемент первой половины вектора, а указатель
high2
— на максимальный элемент второй половины. Графически это можно изобразить следующим образом:

В качестве аргументов функции

high
мы использовали указатели. Этот механизм управления памятью относится к слишком низкому уровню и уязвим для ошибок. Мы подозреваем, что большинство программистов для поиска максимального элемента в векторе написали бы нечто вроде следующего:

double* find_highest(vector<double>& v)

{

double h = –1;

double* high = 0;

for (int i=0; i<v.size; ++i)

if (h<v[i])

{

high = &v[i];

h = v[i];

}

return high;

}

Однако это не обеспечивает достаточно гибкости, которую мы “случайно” уже придали функции

high
, — мы не можем использовать функцию
find_highest
для поиска наибольшего элемента в части вектора. На самом деле, “связавшись с указателями”, мы достигли практической выгоды, получив функцию, которая может работать как с векторами, так и с массивами. Помните: обобщение может привести к функциям, которые позволяют решать больше задач.

  • Читать дальше
  • 1
  • ...
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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