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

Программирование в среде Visual C++ 6. Учебное пособие

.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
1 Мб
Скачать
☆
Шаг интегрирования начинается с формирования аргу­ментов функции вправой части нашего уравнения, как по­казано впервой строке таблицы 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 нужно щёлкнуть, обратите внимание, правой кнопкой ма­нипулятора пункт CDiurView, ивпоявившемся окне уже левой кнопкой манипулятора щёлкнуть на пункт ADD Member Function, наэкране монитора появится окно, как нарис.8.12.
Рис.8.12. Окно создания члена-функции
В окошке Function Type нужно указать тип функции. Так
как она использует только переменные своего класса иневоз­вращает вычисленного значения, нужно указать тип void. Вокошке Function Declaration нужно дать её описание, как кней обращаться: func (). Функция создана. Раскройте класс CDiurView, вы увидите нашу функцию. Если щёлкнуть ле­вой кнопкой манипулятора наеё имя, наэкране монитора по-
— 82 —
явится её заготовка, вкоторой инужно записать операторы вычисления функции.
Здесь будет только один оператор:
fn=a1*yn*yn*exp (xn) +a2*yn;
В этой строчке есть функция экспоненты, описание кото­рой находится вфайле math.h. Нужно этот файл присоеди­нить кпрограмме класса CDiurView. Для этого поднимите курсор наначало файла класса CDiurView после строк при­соединения вставьте оператор
#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 Diur.exe (за- пуск программы Diur.exe). Второй способ — это запуск поумолчанию. Нужно впапке C:\Visual\ Diur\Debug найти файл Diur.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 —
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]