Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

c++ / Лаб 5. Операторы цикла (продолжение)

.pdf
Скачиваний:
60
Добавлен:
18.03.2015
Размер:
419.35 Кб
Скачать

Лабораторная работа №5

Тема: Операторы цикла (продолжение).

Цель: получение практических навыков в работе с операторами цикла языка C.

Темы для предварительной проработки

Операторы цикла языка C. Вложенные циклы. Условный оператор языка C.

Задание для выполнения

Для функции Y = f(X), график которой приведен в Вашем индивидуальном задании, вывести на экран значения Y для Х = 0, 0.25, 0.5, ... 19.75. Необязательное для выполнения дополнительное требование - получить на экране график функции средствами текстового режима.

Варианты индивидуальных заданий

1.

2.

3.

4.

5.

6.

7.

8.

9.

10.

11.

12.

13.

14.

15.

16.

17.

18.

19.

20.

21.

22.

23.

24.

25.

26.

27.

28.

29.

30.

Пример решения задачи (вариант 30)

Разработка алгоритма решения.

Общий метод решения

Из приведенного в индивидуальном задании графика функции видно, что функция является периодической, с периодом 4. В заданный интервал вкладываются 5 периодов функции. Так что, программа может содержать в себе цикл, в котором 5 раз будут выполняться одни и те же вычисления. В каждой итерации этого цикла должны перебираться значения x от 0 до 3.75 с шагом 0.25, т.е., должен быть вложенный цикл. В каждой итерации вложенного цикла вычисляется значение y для текущего x и выводятся результаты.

Анализ приведенного графика показывает, что каждый период его состоит из трех частей: на отрезке 0<=x<=1 график является прямой, на отрезке 1<=x<=3 - дугой, а на отрезке 3<=x<=4 - другой прямой. Следовательно, во вложенном цикле должно быть разветвление, в котором определяется текущее значение x и обеспечиваются вычисления для первого, второго или третьего случая.

Вычисление функции на отрезке 0 - 1

На этом отрезке функция является функцией прямой. Формула прямой: y=ax+b. Для этого случая a=2, b=-1. Итак, окончательная формула для отрезка 0<=x<=1 такая:

y=2x-1

Вычисление функции на отрезке 1 - 3

На этом отрезке функция является частью окружности. Формула окружности:

(x-x0)2+(y-y0)2=R2, где (x0, y0) - координаты центра окружности, а R - радиус.

Отсюда y можно определить как: . В нашем случае R=1, а координаты центра - (2, 1). Извлечение квадратного корня дает два значения - положительное и отрицательное, в нашем случае используется только нижняя полуокружность, так что следует брать только отрицательное значение. Окончательная формула для отрезка

1<=x<=3 такая: y=2-((1-(x-2)2)

Вычисление функции на отрезке 3 - 4

Для прямой на этом отрезке a=-2, b=7, окончательная формула: y=7-2x

Алгоритм вывода результатов в псевдографической форме

Вкаждой итерации внутреннего цикла мы получает одну ординату графика. Следовательно, для представления результата в псевдографической форме будет удобно развернуть график на 90о и в каждой строке экрана отображать значения x, y и символ, который изображает одну точку графика, смещение этого символа в строке будет пропорционально значению ординаты. Для отображения этого символа с необходимым смещением нужно преобразовать ординату в целое число (с масштабированием к размеру строки), это число будет количеством пробелов, которое нужно вывести в строке перед символом-"точкой".

Вкаждый период функции вкладывается 16 итераций внутреннего цикла, т.е. на экран будет выведено 16 строк на период. Целесообразно после вывода каждого периоду (который целиком помещается на экране) делать остановку в программе до команды оператора на продолжение.

Схема алгоритма

Определение переменных программы

Для реализации алгоритма понадобятся такие переменные:

n - параметр внешнего цикла, для него достаточно короткого целого значения: short n;

x - параметр внутреннего цикла и одновременно - текущее значение абсциссы графика. Хотя его точность невелика, объявим его как double, в соответствии с общим стилем программирования на С.

double x;

y - текущее значение ординаты графика: double y;

h - смещение в строке символа, который означает точку графика. Поскольку смещение не может превышать 80 (размер строки экрана), для этой переменной достаточно будет короткого целого: short h;

Разработка текста программы

Начинаем разработку текста программы с заголовка главной функции: int main(void)

Далее открывается тело функции, и в него включаются объявления переменных. Кодовая часть программы начинается в соответствии со схемой алгоритма (блок

2) оператором-заголовком внешнего цикла. Это типичный цикл со счетчиком, он реализуется оператором: for (n=0; n<5; n++) {

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

В теле цикла прежде всего печатается заголовок таблицы (блок 3) операторами: printf("| X | Y |\n");

printf("|------------|------------|\n");

После этого открываем внутренний цикл (блок 4). Параметр этого цикла - значение абсциссы x - принимает значения от 0 до 3.75 с шагом 0.25:

for (x=0; x<4; x+=0.25) {

Блок 5 схемы алгоритма (проверка попадания на первый отрезок) реализуется условным оператором: if (x<1)

Вслучае выполнения этого условия, значение абсциссы вычисляется (блок 7) по уравнению для первой прямой: y=2*x-1;

Если же предыдущее условие не выполняется, блок 6 схемы алгоритма (проверка попадания на второй отрезок) реализуется условным оператором: else if (x<3)

Вслучае выполнения этого условия, значение абсциссы вычисляется (блок 8) по уравнению для полуокружности: y=1-sqrt(1-(x-2)*(x-2));

Вэтом выражении для возведения в степень 2 применяется умножение. Функция sqrt() описана в файле math.h, так что включаем этот файл в начало программы:

#include <math.h>

Если же и это условие не выполняется, то мы имеем попадание на третий отрезок,

изначение абсциссы вычисляется (блок 9) по уравнению для второй прямой:

else y=7-2*x;

Во внутреннем цикле мы выполняем вычисления для одного периода функции, но внешний цикл выполняется у нас 5 раз. Реальное значение абсциссы с учетом внешнего цикла составляет x+4n. Теперь, когда мы имеем абсциссу и ординату графика, можем выводить строку выходных данных (блок 10). Сперва выводим строку таблицы: printf("| %5.2lf | %10.7lf | ",x+n*4,y);

Спецификации формата подобраны таким образом, чтобы значения x и y выводились в два столбца. Числовые параметры спецификации %lf должны обеспечить представление значений x и y с достаточной точностью. Функция printf() описана в файле stdio.h, поэтому мы включаем этот файл в начало программы:

#include <stdio.h>

Следующий шаг - вывод в той же строку точки графика. После вывода строки таблицы в строке экрана осталось 57 свободных знакомест. На этом пространстве нам нужно показать значения y от -1 до +1. Если мы возьмем коэффициент масштабирования 10, то амплитуда графика составит 20 знакомест - достаточно для наглядного его представления. Масштабирование значения ординаты выполняется оператором: h=(y+1)*10;

Выбранное значение коэффициента масштабирования - 10 - может быть изменено при отладке).

При выполнении последнего оператора мы теряем дробную часть. Поскольку среди библиотечных функций языка C нет функции точного округления, мы выполняем такое округление сами: if (y-1-h*10>0.5) h++;

Далее в строку экрана выводится (блоки 12-13) требуемое количество пробелов. В следующем цикле полученное ранее значение h работает как счетчик на вычитание.

for (; h>0; h--) printf(" ");

а потом выводится символ '*' и происходит переход на новую строку экрана: printf("*\n");

На этом заканчивается внутренний цикл.

После выхода из внутреннего цикла мы выводим сообщение оператору: printf("Нажмите клавишу Enter...");

И ждем нажатия клавиши: getchar();

На этом закрывается внешний цикл, а потом и тело функции main(). Полный текст программы.

#include "stdafx.h" #include <iostream> #include <iomanip> #include <conio.h> #include <math.h> #include <windows.h>

int _tmain(int argc, _TCHAR* argv[])

{setlocale(0,"Rus");

 

 

 

short n;

/*

параметр внешнего цикла */

double x, y;

/*

абсцисса и ордината графика */

short h;

/*

позиция точки на экране */

/* внешний цикл

- для 5 периодов */

for (n=0; n<5; n++) {

 

 

/* вывод заголовка

таблицы */

 

printf("|

x

|

y

|\n");

printf("|-------|------------|\n");

/* внутренний цикл для одного периода */ for (x=0; x<4; x+=0.25) {

/* 1-й отрезок */

if (x<1) y=2*x-1; /* 2-й отрезок */

else if (x<3) y=1-sqrt(1-(x-2)*(x-2)); /* 3-й отрезок */

else y=7-2*x;

/* вывод строки таблицы */ printf("| %5.2lf | %10.7lf |",x+n*4,y);

/* определение позиции точки */ h=(y+1)*10;

if (y-1-h*10>0.5) h++;

/* вывод точки графика */

for (; h>0; h--) printf(" "); printf("*\n");

} /* конец внутреннего цикла */ /* пауза до команды оператора */

printf("Нажмите клавишу Enter..."); getchar();

} /* конец внешнего цикла */ getch();

return 0;

} /* конец программы */

Отладка программы

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

убедиться в правильной организации внешнего и внутреннего циклов;

убедиться в правильной работе цепочки условий, которые определяют отрезок;

убедиться в правильном вычислении значения ординаты на первом отрезке (только по числовым значениям);

на примере первого отрезка убедиться в правильном выводе графика;

убедиться в правильном вычислении значения ординаты на втором отрезке;

убедиться в правильном вычислении значения ординаты на третьем отрезке.

Результаты работы программы

Мы приводим только часть результатов, полученных на экране при работе

программы (для одного периода функции). Остальные результаты повторяют приведенные с другими значениями x.