Приложение. Использование манипуляторов для форматирования потокового ввода-вывода.
Лабораторная работа 3, 4, 5
Программирование циклических алгоритмов
3.1. Обработка одномерных массивов
3.2. Обработка двумерных массивов
3.3. Вычисление суммы бесконечного ряда с заданной точностью
Цель работы
Целью работы является приобретение студентами следующих навыков:
- использование операторов for, while и do-while при программировании циклических алгоритмов;
- использование вложенных циклов;
- преобразование исходных выражений с целью получения эффективных (с точки зрения точности получаемых результатов и времени выполнения) расчетных соотношений при выполнении расчетов по формулам;
- изображение циклов for, while и do-while на схемах алгоритмов;
- использование манипулятора setw для форматирования потокового вывода (см. Приложение).
Указания по выполнению работы
Задача 1.
Для повторения или завершения выполнения программы используйте цикл do … while, который должен включать в себя запрос “Продолжить работу? (y/n)” и ввод с клавиатуры соответствующего символа. Это позволит запускать программу с новыми данными, не завершая ее. Используйте такой прием в тех случаях, когда требуется многократно запускать программу с различными исходными данными (например, для отладки или демонстрации работы преподавателю).
Задача 2.
Обеспечьте нужную точность представления результата, используя манипулятор setprecision(n) для потокового вывода.
Задача 3.
При вычислении значения очередного члена ряда используйте рекуррентные соотношения, которые должны быть составлены на основе предварительно выявленной взаимосвязи между членами ряда.
Заданная точность обеспечивается суммированием членов ряда вплоть до слагаемого, абсолютное значение которого меньше заданной погрешности (Например: 0.001, 0.0001,…, 0.000001).
Значения математических констант, таких как pi, e, хранятся в файле math.h. Так как их значения не определены в стандарте языка С++, то при простом включении файла в программу эти константы недоступны. Для доступа к ним необходимо перед оператором препроцессора #include <math.h> выполнить оператор #define _USE_MATH_DEFINES . Имена констант найдите в файле math.h.
Пример(3.1) Формирование элементов одномерного массива в заданном диапазоне значений с помощью функции случайных чисел
#include "stdafx.h"
#include <iostream>
#include <conio.h>
#include <cmath>
#include <Windows.h>
#include <stdlib.h>
#include <time.h>
#include <clocale>
using namespace std;
#include <iomanip>
#define N 20
int main()
{int mas[N]={0};
char ch;
do
{int a,b;
setlocale(LC_CTYPE, "rus"); // выполняет перекодировку символов в соответствии с требуемым языком
srand(time(NULL));
cout<<"Введите границы диапазона значений элементов массива:";
cin>>a>>b;
for (int i=0; i<N; i++)
{mas[i]=a+rand()%(b-a+1);
cout<<"mas["<<setw(2)<<i<<"]="<<mas[i]<<endl; //Вывод элементов массива в столбец
}
cout<<"Вывод элементов массива в строку:"<<endl;
for (int i=0; i<N; i++)
cout<<setw(8)<<mas[i];
cout<<endl;
_getch();
cin>>ch;
} while ((ch=='Y')||(ch=='y'));
return 0;
}
Задание
1. Составьте блок-схему алгоритма примера 3.1.
2. Сохраните результаты работы программы для различных значений a и b.
3. Модифицируйте программу для получения вещественных значений элементов массива.
4. Найдите и запишите назначение всех используемых в программе директив.
Приложение. Использование манипуляторов для форматирования потокового ввода-вывода.
Несмотря на гибкость и большие возможности управления форматами с помощью компонентных функций класса ios, их применение достаточно громоздко. Более простой способ изменения параметров и флагов форматирования обеспечивают манипуляторы.
Манипуляторами называют специальные функции, позволяющие программисту изменять состояния и флаги потока. Особенность манипуляторов и их отличие от обычных функций состоит в том, что их имена (без параметров) и вызовы (с параметрами) можно использовать в качестве правого операнда для операции обмена (<< или >>). В качестве левого операнда в этом выражении, как обычно, используется поток (ссылка на поток), и именно на этот поток оказывает влияние манипулятор.
Например, манипулятор hex позволяет устанавливать шестнадцатеричное основание счисления выводимых в поток cout числовых значений. Выполнив последовательность операторов:
cout << "\nДесятичное число: "<< 15 << hex;
cout << "\nШестнадцатеричное представление: "<< 15;
получим на экране:
Десятичное число: 15
Шестнадцатеричное представление: 0xF
Как наглядно показывает результат, применение манипулятора hex изменило одно из свойств потока cout. Десятичная целая константа 15 воспринимается и выводится на экран в шестнадцатеричном виде.
В качестве примера каждый манипулятор автоматически (без явного участия программиста) получает ссылку на тот поток, с которым он используется в выражении. После выполнения манипулятора он возвращает ссылку на тот же поток. Поэтому манипуляторы можно использовать в цепочке включений в поток или извлечений из потока. При выполнении манипулятора никаких обменов данными с потоком не происходит, но манипулятор изменяет состояние потока. Например, выполнив оператор с манипуляторами hex, oct, dec:
cout << 15 << hex << 15 << oct << 15 << dec<< 15;
в качестве результата получим:
150xF01715
Манипуляторы библиотеки классов ввода-вывода языка Си++ делятся на две группы: манипуляторы с параметрами и манипуляторы без параметров.
Манипуляторы без параметров:
dec - при вводе и выводе устанавливает флаг десятичной системы счисления;
hex - при вводе и выводе устанавливает флаг шестнадцатеричной системы счисления;
oct - при вводе и выводе устанавливает флаг восьмеричной системы счисления;
ws - действует только при вводе и предусматривает извлечение из входного потока пробельных символов (пробел, знаки табуляции '\t’и ' \v’, символ перевода строки '\n', символ возврата каретки '\r', символ перевода страницы’ \f’);
endl - действует только при выводе, обеспечивает включение в выходной поток символа новой строки и сбрасывает буфер (выгружает содержимое) этого потока;
ends - действует только при выводе и обеспечивает включение в поток нулевого признака конца строки;
flush - действует только при выводе и очищает выходной поток, т.е. сбрасывает его буфер (выгружает содержимое буфера).
left -вывод значения с левым выравниванием (прижать к левому краю поля);
right -вывод значения с правым выравниванием (это значение устанавливается по умолчанию);
fixed -для вещественных чисел (типов float, double)используется представление в формате с фиксированной точкой, причем количество цифр дробной части определяется заданной точностью.
Обратите внимание, что не все перечисленные манипуляторы действуют как на входные, так и на выходные потоки, ws действует только при вводе; endl, ends, flush - только при выводе.
Манипуляторы dec, hex, oct, задающие основание системы счисления, изменяют состояние потока, и это изменение остается в силе до следующего явного изменения.
Манипулятор endl рекомендуется использовать при каждом выводе, который должен быть незамедлительно воспринят пользователем. Например, его использование просто необходимо в таком операторе:
cout << "Ждите! Идет набор статистики." << endl ;
При отсутствии endl здесь нельзя гарантировать, что сообщение пользователю не останется в буфере потока cout до окончания набора статистики.
Манипуляторы с параметрами определены в файле iomanip:
setbase(int n);
устанавливает основание (n) системы счисления. Значениями параметра n могут быть: 8, 10 или 16.
resetiosflags(long L)
сбрасывает (очищает) отдельные флаги состояния потоков ввода и вывода на основе битового представления значения параметра L (сбрасывает флаги в соответствии с единичными битами);
setiosflags(long L)
устанавливает отдельные флаги состояния (форматные биты) потоков ввода-вывода на основе битового представления значения параметрах (устанавливаются флаги в соответствии с единичными битами параметра);
setfill(int n)
значение параметра n в дальнейшем используется в качестве кода символа-заполнителя, который помещается в незанятых позициях поля при вводе значения.
setprecision(int n)
определяет с помощью значения параметра n точность представления вещественных чисел, т.е. максимальное количество цифр дробной части числа при вводе и выводе.
setw(int n)
значение параметра n задает минимальную ширину поля вывода.
С помощью манипуляторов можно управлять представлением информации в выходном потоке. Например, манипулятор setw(int n) позволит выделить для числового значения поле фиксированной ширины, что удобно при печати таблиц.