Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Программирование в среде Visual C++ 6. Учебное пособие
.pdf
Шаг интегрирования начинается с формирования аргументов функции вправой части нашего уравнения, как показано впервой строке таблицы 8.1.
xn=xy [0] [i];
yn=xy [1] [i];
Теперь нужно вычислить функцию правой части уравнения. Её пока нет. Создадим её несколько позже, асейчас положим, что она есть иеё имя func (), арезультат её вычисления будет переменная fn.
Не забудьте, что идентификаторы xn, yn, fn, атакже k1, k2,
k3, k4 нами были уже описаны ранее. Исразуже вычислим
переменную k1:
func ();
k1=fn*h;
Теперь перейдём ковторой строке таблицы 8.1:
xn=xy [0] [i] +h/2.0;
yn=xy [1] [i] +k1/2.0;
func ();
k2=fn*h;
Аналогично запрограммируем третью ичетвёртую строчки таблицы 8.1:
yn=xy [1] [i] +k2/2.0;
func ();
k3=fn*h;
xn=xy [0] [i] +h;
yn=xy [1] [i] +k3;
func ();
k4=fn*h;
Теперь запишем значения следующей строки таблицы интегрирования: x увеличим навеличину шага, аy навеличину,
рассчитанную поформуле под таблицей 8.1:
— 81 —

xy [0] [i+1] =x [0] [i] +h;
xy [1] [i+1] =xy [1] [i] + (k1+k2*2.0+k3*2.0+k4) /6.0;
}
Процесс интегрирования закончен, итаблица результатов
интегрировании xy заполнена.
В цикловой программе интегрирования мы писали об-
ращение кфункции func (), которой ещё нет. Нужно создать эту функцию. Так как интегрирование производится в классе представления, то и функцию нужно создать
в этом же классе. Для этого в окне Workspase — Classes
нужно щёлкнуть, обратите внимание, правой кнопкой манипулятора пункт CDiurView, ивпоявившемся окне уже
левой кнопкой манипулятора щёлкнуть на пункт ADD
Member Function, наэкране монитора появится окно, как
нарис.8.12.
Рис.8.12. Окно создания члена-функции
В окошке Function Type нужно указать тип функции. Так
как она использует только переменные своего класса иневозвращает вычисленного значения, нужно указать тип void.
Вокошке Function Declaration нужно дать её описание, как
кней обращаться: func (). Функция создана. Раскройте класс
CDiurView, вы увидите нашу функцию. Если щёлкнуть левой кнопкой манипулятора наеё имя, наэкране монитора по-
— 82 —

явится её заготовка, вкоторой инужно записать операторы
вычисления функции.
Здесь будет только один оператор:
fn=a1*yn*yn*exp (xn) +a2*yn;
В этой строчке есть функция экспоненты, описание которой находится вфайле math.h. Нужно этот файл присоединить кпрограмме класса CDiurView. Для этого поднимите
курсор наначало файла класса CDiurView после строк присоединения вставьте оператор
#include “math.h”
8.12. Построение графика
Теперь вернёмся кнашей основной функции OnDraw ипро-
должим дальше составлять нашу программу. Так как таблица xy
уже составлена, её следует вывести наэкран монитора. Для этого воспользуемся цикловой программой печати каждой строки
изn+1. (число интервалов n, следовательно, число строк n+1).
Заголовок этой цикловой программы будет иметь вид:
for (i=0; i<n+1; i++)
{
Не забудьте несколькими строками ниже поставить закрывающую фигурную скобку. Далее каждая строчка выводится
наэкран монитора спомощи четырёх операторов, при этом
каждая строка понижается вниз поэкрану на20 пикселей:
sprintf (s,”%6.4f ”, xy [0] [i]);
pDC->TextOut (820,60+i*20, s);
sprintf (s,”%6.4f ”, xy [1] [i]);
pDC->TextOut (920,60+i*20, s);
}
Теперь осталось написать программу вывода графика полученной нами функции путём интегрирования нашего диф-
— 83 —

ференциального уравнения. Разместим наш график в прямоугольнике по горизонтальной оси в пределах 100…500
иповертикальной оси впределах 200…400.. Для начала вычертим координатные линии уже известным нам способом:
for (i=0; i<5; i++)
{
pDC->MoveTo (100,200+i*50);
pDC->LineTo (500,200+i*50);
}
for (i=0; i<6; i++)
{
pDC->MoveTo (100+i*80,200);
pDC->LineTo (100+i*80,400);
}
Теперь нужно разметить координатные оси. Так как значения координат будут находиться в пределах 0…1, то по
оси ординат нужно записать значения 0, 0.25, 0.50, 0.75 и1.0,
апооси абсцисс значения 0, 0.2, 0.4, 0.6,, 0,8 и1.0. Это тоже
можно сделать спомощью цикловых программ.
yn=1.0;
for (i=0; i<5; i++)
{
sprintf (s,”%3.2f ”, yn);
pDC->TextOut (50,190+i*50, s);
yn- =0.25;
}
pDC->TextOut (66,170,”y”);
xn=0.0;
for (i=0; i<6; i++)
{
sprintf (s,”%2.1f ”, xn);
— 84 —

pDC->TextOut (90+i*80,420, s);
xn+=0.2;
}
pDC->TextOut (530,420,»x»);
Все числа в приведённых операторах можно рассчитать,
исходя из того, что ширина каждого символа составляет 8
пикселей. Затем путём исправления этих чисел имногократного компилирования и запуска нашей программы можно
уточнить их для наиболее удобного расположения элементов
нашего графика.
Осталось только выделить координатные оси, проведя
линии рядом скоординатными осями нарасстоянии водин
пиксель. Получились линии толщиной вдва пикселя. Это следующие ипоследние три операторы:
pDC->MoveTo (99,200);
pDC->LineTo (99,401);
pDC->LineTo (500,401);
Теперь приступим к вычерчиванию самого графика. Для
начала рассчитаем число пикселей экрана монитора наединицу координатной оси. Нотак как унас оси ограничиваются
единичными значениями координат, товычисляемые значения просто равны длине осей. Оба операторы имеют вид:
dxx=400.0;
dyy=200.0;
Вычислим начальную точку и установим там курсор.
Погоризонтальной оси это просто начало её, аповертикальной оси нужно от начала её вычесть количество пикселей
начальной точки таблицы xy. Это просто нужно умножить
величину dyy наординату начала кривой.
pDC->MoveTo (100,400-int (xy[1] [0] *dyy));
— 85 —

Обратите внимание, что это произведение взято в скоб-
ках, аперед ней стоит наименование типа int. Вданном случае это нефункция int, а указание компилятору, что нужно
вычисленное значение типа double преобразовать втип целого числа int. Без этого указания компилятор выдаёт либо
предупреждение, либо ошибку, так как вязыке непредусмотрено преобразование изdouble вint поумолчанию. Все
линии, соединяющие точки нашей кривой, вычерчиваются
по циклической программе, где координаты конца каждого
отрезка вычисляются также как иранее вфункции MoveTo.
for (i=1; i<n+1; i++)
pDC->LineTo (100+int (xy[0] [i] *dxx),400-int (xy[1] [i]
*dyy));
}
Всё, наше приложение составлено. Осталось сравнить
сприведёнными вприложении листингами отдельных программ, и можно провести окончательное компилирование
нашей программы.
— 86 —

9.
Запуск нашего приложения можно производить двумя
способами. Первый способ— это использовать меню среды
Visual C++. Для этого достаточно щёлкнуть левой кнопкой
манипулятора напункт меню Build— Execute Diur.exe (за-
пуск программы Diur.exe). Второй способ — это запуск
поумолчанию. Нужно впапке C:\Visual\ Diur\Debug найти
файл Diur.eexe и щёлкнуть левой кнопкой манипулятора.
Наэкране монитора появится окно, как нарис.9.1.
Рис.9.1. Начальное окно после запуска приложения
Здесь показаны меню, панель управления, заголовок нашей программы, заданное уравнение и исходные данные
по умолчанию. Если Ваши исходные данные не совпадают
сприведёнными, нужно левой кнопкой манипулятора щёлкнуть либо напункт меню — , либо напункт
панели управления. Наэкране монитора появится дополнительно диалоговое окно, как нарис.9.2.
Вводить имеет смысл только те данные, которые не совпадают с приведёнными по умолчанию. В нашем случае
— 87 —

это параметр a2 иn. Левой кнопкой манипулятора поставим
точку вкнопке сименем a2 испомощью клавиатуры влевом
окошечке редактирования наберём значение этого параметра. Вэтом окошечке при необходимости можно многократно проводить редактирование этого значения. Затем нужно
щёлкнуть левой кнопкой манипулятора накнопку . Вы
заметите, что значение этого параметра на экране монитора изменилось. Если изменения опять несоответствуют заданию, эту процедуру можно многократно повторить. Тоже
самое можно произвести и с другими переменными. Когда
убедитесь, что все исходные данные соответствуют заданию,
левой кнопкой манипулятора щёлкните на кнопку ,
идиалоговое окно исчезнет сэкрана монитора.
Рис.9.2. Диалоговое окно
— 88 —

Теперь можно запустить процесс интегрирования заданного дифференциального уравнения. Для этого нужно щёлкнуть левой кнопкой манипулятора либо на пункт
меню — , либо напункт панели управления.
Наэкране монитора появится окно срезультатами вычисления, как нарис.9.3.
Рис.9.3. Окно срезультатами вычислений
Здесь приведены исходные данные, таблица вычислений
и соответствующий график проинтегрируемого дифференциального уравнения. Можно повторить интегрирование
с меньшим числом интервалов, например, n=10. Вы убедитесь, что результаты не изменились. Это значит, что наша
функция вычислена сточными четырьмя знаками после десятичной точки.
— 89 —

10. P VISUAL C++6
10.1. Сохранение ивосстановление данных
Часто при работе составленных рабочих программ требуется сохранить некоторые текущие данные, чтобы потом воспользоваться ими вдругих частях нашей программы или вдругих рабочих программах. Особенно это необходимо впроектах
с несколькими документами. Если объём данных незначителен, тоэто можно осуществить методом Serialize. Вклассе документов висходной части только что образованного проекта включена функция void C… Doc:: Serialize (CArchive& ar)
саргументом CArchive& ar. Это класс архива, представляюще-
го набор возможных файлов нажёстком диске, образованных
рабочей программой. Эти файлы можно расположить где угодно, нобез указания пути эти файлы располагаются вфайловом
пространстве разрабатываемого проекта.
При формировании меню (см. пункт 8.4) висходном меню
нужно оставить пункты меню, работающие сфайлами. Это
New, Open, Save, Save As, Close. При желании эти названия
пунктов меню можно заменить насоответствующие русские:
, , , , . Эти
пункты спокойно перейдут вменю нашей рабочей программы. В пункте меню Edit — из свободных
пунктов организовать отдельные пункты меню для каждой
группы переменных, которые необходимо сохранять ивосстанавливать. Естественно, что все эти переменные должны быть объявлены в классе документов. Имена этих пун-
— 90 —
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
