ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В C++ (4-Е ИЗДАНИЕ) (часть 7) онлайн

Упражнения

Решения к упражнениям, помеченным знаком *, можно найти в приложении Ж. *1. Напишите функцию reversit(), которая переворачивает строку (массив типа                 char). Используйте цикл for, который меняет местами первый и последний                 символы, затем следующие и т. д. до предпоследнего. Строка должна пере-                 даваться в функцию reversit() как аргумент.

Напишите программу для выполнения функции reversit(). Программа долж- на принимать строку от пользователя, вызывать функцию reversit(), а за- тем выводить полученный результат. Используйте метод ввода, который позволяет использовать внутренние пробелы. Протестируйте программу на примере фразы «Аргентина манит негра».

*2. Создайте класс employee, который содержит имя (объект класса string) и но- мер (типа long) служащего. Включите в него метод getdata(), предназна- ченный для получения данных от пользователя и помещения их в объект, и метод putdata(), для вывода данных. Предполагаем, что имя не может иметь внутренних пробелов.

Напишите функцию main(), использующую этот класс. Вам нужно будет создать массив типа employee, а затем предложить пользователю ввести данные до 100 служащих. Наконец, вам нужно будет вывести данные всех служащих.

*3. Напишите программу, вычисляющую среднее значение до 100 интервалов, введенных пользователем. Создайте массив объектов класса Distance, как это было сделано в примере ENGLARAY этой главы. Для вычисления сред- него значения вы можете позаимствовать метод add_dist() из примера ENGLCON главы 6. Вам также понадобится метод, который выделяет целую часть из значения Distance. Вот одна из возможностей:

void Distance::div_dist ( Distance d2, int divisor )

{

                float fltfeet = d2.feet + d2.inches / 12.0;

                float temp = fltfeet /= divisor;

                feet = int ( fltfeet );

                inches = ( temp - feet ) * 12.0;

}

 

4. Начните с программы, которая позволяет пользователю вводить целые чис- ла, а затем сохранять их в массиве типа int. Напишите функцию maxint(), которая, обрабатывая элементы массива один за другим, находит наиболь- ший. Функция должна принимать в качестве аргумента адрес массива и количество элементов в нем, а возвращать индекс наибольшего элемента. Программа должна вызвать эту функцию, а затем вывести наибольший элемент и его индекс. (Смотрите программу SALES этой главы.)

5. Начните с класса fraction из упражнений 11 и 12 главы 6. Напишите функцию main(), которая получает случайные дробные числа от пользова- теля, сохраняет их в массиве типа fraction, вычисляет среднее значение и выводит результат.

6. В игре бридж каждому из игроков раздают 13 карт, таким образом коло- да расходуется полностью. Модифицируйте программу CARDARAY этой главы так, чтобы после перемешивания колоды она делилась на четыре части по 13 карт каждая. Каждая из четырех групп карт затем должна быть выведена.

7. Одним из недостатков C++ является отсутствие для бизнес-программ встроенного типа для денежных значений, такого, как $173 698 001,32. Такой денежный тип должен иметь возможность для хранения числа с фиксированной десятичной точкой точностью около 17 знаков, которого было бы достаточно для хранения национального долга в долларах и цен- тах. К счастью, встроенный тип C++ long double имеет точность 19 цифр, поэтому мы можем использовать его как базисный для класса money, даже используя плавающую точку. Однако нам нужно будет добавить возмож- ность ввода и вывода денежных значений с предшествующим им знаком доллара и разделенными запятыми группы по три числа: так проще читать большие числа. Первым делом при разработке такого класса напишем ме- тод mstold(), который принимает денежную строку, то есть строку, пред- ставляющую собой некоторое количество денег типа

                "$1,234,567,890,123.99"

в качестве аргумента и возвращает эквивалентное ее значению число типа long double.

Вам нужно будет обработать денежную строку как массив символов и, просматривая ее символ за символом, скопировать из нее только цифры (0-9) и десятичную точку в другую строку. Игнорируется все остальное, включая знак доллара и запятые. Затем вы можете использовать биб- лиотечную функцию _atold() (заметим, что здесь название функции на- чинается с символа подчеркивания — заголовочные файлы STDLIB.H или MATH.H) для преобразования новой строки к числу типа long double. Пред- полагаем, что денежное значение не может быть отрицательным. Напи- шите функцию main() для проверки метода mstold(), которая несколько раз получает денежную строку от пользователя и выводит соответству- ющее число типа long double.

8. Другим недостатком C++ является отсутствие автоматической проверки индексов массива на соответствие их границам массива (это делает дей- ствия с массивами быстрыми, но менее надежными). Мы можем исполь- зовать класс для создания надежного массива, который проверяет индек- сы при любой попытке доступа к массиву.

Напишите класс safearay, который использует массив типа int фиксиро- ванного размера (назовем его LIMIT) в качестве своей единственной пере- менной. В классе будет два метода. Первый, putel(), принимает индекс и значение типа int как аргументы и вставляет это значение в массив по за- данному индексу. Второй, getel(), принимает индекс как аргумент и воз- вращает значение типа int, содержащееся в элементе с этим индексом.

safearay sa1;     // описываем массив

int temp = 12345;                            // описываем целое

sa1.putel ( 7, temp );     // помещаем значение temp в массив

temp = sa1.getel (7);     // получаем значение из массива

Оба метода должны проверять индекс аргумента, чтобы быть уверенны- ми, что он не меньше 0 и не больше, чем LIMIT-1. Вы можете использовать этот массив без опаски, что запись будет произведена в другие части па- мяти.

Использование методов для доступа к элементам массива не выглядит так наглядно, как использование операции [ ]. В главе 8 мы увидим, как перегрузить эту операцию, чтобы сделать работу нашего класса safearay похожей на работу встроенных массивов.

9. Очередь — это устройство для хранения данных, похожее на стек. Отли- чие в том, что в стеке последний сохраненный элемент будет первым извлеченным, тогда как в очереди первый сохраненный элемент будет первым извлеченным. То есть в стеке используется подход «последний вошел — первый вышел» (LJFO), а в очереди используется подход «пер- вый вошел — первый вышел» (FIFO). Очередь похожа на простую оче- редь посетителей магазина: первый, кто встал в очередь, будет обслужен первым.

Перепишите программу STAKARAY из этой главы, включив в нее класс queue вместо класса stack. Кроме того, класс должен иметь два метода: один, называемый put(), для помещения элемента в очередь; и другой, на- зываемый get(), для извлечения элемента из очереди. Эти методы эквива- лентны методам push() и pop() класса stack.

Оба класса, stack и queue, используют массив для хранения данных. Одна- ко вместо одного поля top типа int, как в классе stack, вам понадобятся два поля для очереди: одна, называемая head, указывающая на начало очере- ди; и вторая, tail, указывающая на конец очереди. Элементы помещаются в конец очереди (как посетители банка, становящиеся в очередь), а извле- каются из начала очереди. Конец очереди перемещается к началу по мас- сиву по мере того, как элементы добавляются и извлекаются из очереди. Такие результаты добавляют сложности: если одна из двух переменных

head или tail примут значение конца массива, то следует вернуться на на- чало. Таким образом, вам нужно выражение типа

                if ( tail == MAX - 1 )                 tail = -1;

для возврата переменной tail и похожее выражение для возврата перемен- ной head. Массив, используемый в очереди, иногда называют круговым буфером, так как начало и конец очереди циркулируют по нему вместе с ее данными.

10. Матрица — это двумерный массив. Создайте класс matrix, который пре- доставляет те же меры безопасности, как и класс из упражнения 7, то есть осуществляет проверку индексов массива на вхождение их в границы массива. Полем класса matrix будет массив 10 на 10. Конструктор должен позволять программисту определить реальный размер массива (допустим, сделать его меньше, чем 10 на 10). Методам, предназначенным для досту- па к членам матрицы, теперь нужны два индекса: по одному для каждой размерности массива. Вот фрагмент функции main(), которая работает с таким классом:

matrix m1 ( 3, 4 );            // описываем матрицу

int temp = 12345;            // описываем целое

ml.putel ( 7, 4, temp ); // помещаем значение temp в матрицу

temp = m1.getel ( 7, 4 ); // получаем значение из матрицы

11.          Вернемся к обсуждению денежных строк из упражнения 6. Напишите ме- тод ldtoms() для преобразования числа типа long double в денежную строку, представляющую это число. Для начала вам нужно проверить, что значе- ние long double не очень большое. Мы предполагаем, что вы не будете пы- таться преобразовать число, больше чем 9 999 999 999 999 990.00. Затем преобразуем long double в строку (без знака доллара и запятых), храня- щуюся в памяти, используя объект ostrstream, как рассматривалось ранее в этой главе. Получившаяся отформатированная строка может быть поме- щена в буфер, называющийся ustring.

Затем вам нужно будет создать другую строку, начинающуюся со знака доллара, далее копируем цифру за цифрой из строки ustring, начиная сле- ва и вставляя запятые через каждые три цифры. Также вам нужно подав- лять нули в начале строки. Например, вы должны вывести $3 124.95, а не $0 000 000 000 003 124.95. Не забудьте закончить строку нулевым симво- лом '\0'.

Напишите функцию main() для тестирования этой функции путем много- кратного ввода пользователем чисел типа long double и вывода результата в виде денежной строки.

12. Создайте класс bMoney. Он должен хранить денежные значения как long double. Используйте метод mstold() для преобразования денежной строки, введенной пользователем, в long double, и метод ldtoms() для преобразова- ния числа типа long double в денежную строку для вывода (см. упражне- ния 6 и 10). Вы можете вызывать для ввода и вывода методы getmoney()

и putmoney(). Напишите другой метод класса для сложения двух объектов типа bMoney и назовите его madd(). Сложение этих объектов легко произ- вести: просто сложите переменную типа long double одного объекта с та- кой же переменной другого объекта. Напишите функцию main(), которая просит пользователя несколько раз ввести денежную строку, а затем вы- водит сумму значений этих строк. Вот как может выглядеть определение класса:

class bMoney {

private:

long double money; public:                 bMoney ( );

bMoney ( char s [ ] );

void madd ( bMoney m1, bMoney m2 );

void getmoney ( );

void putmoney ( );

};

 

 

37