
- •Методические указания по выполнению домашних заданий для студентов 1 курса специальности иу-10.
- •Введение.
- •Домашнее задание 1. Практикум 6. Приближенные вычисления.
- •Задача 6.1.
- •Var a, b, c : real;
- •Iter : longword;
- •Inc(iter);
- •Задания.
- •Задача 6.2.
- •Inc(n); inc(iter);
- •Задания.
- •Практикум 7. Процедурные типы.
- •Задача 7.1.
- •Var a, b, X, dx, y1, y2, s1, s2 : real;
- •Var a, b, X, dx, y1, y2, s1, s2 : real;
- •Inc(iter);
- •Задания.
- •Задача 7.2.
- •Var s1, s2 : real;
- •Задания.
- •Домашнее задание 2. Практикум 13. Типизированные файлы.
- •Задача 13.1.
- •Var I : word;
- •Var I, j : word; buf : tSportMan;
- •If fSort(a[I], a[j]) then
- •Var I : word;
- •Var I : word;
- •Var aHi : Ta; Var nHi : word);
- •Var I : word;
- •Задания.
- •Домашнее задание 3. Практикум 18. Использование объектной технологии для построения движущихся фигур.
- •X, y : real;
- •2*T0.X-border, 2*t0.Y-border);
- •X3, y3 : real;
- •X1, y1, x2, y2, x3, y3 : real;
- •Inherited Init(fx0, fy0, fmx, fcnv);
- •Var t : array[1..3] of tPoint; I : byte;
- •Var t0 : tPoint; tc : trPoint; tri:cTri;
- •0,0, 1,0, 0,1, Tc, clRed);
- •Var I : byte; r, a : real;
- •Var t0 : tPoint; tc : trPoint;
- •0,0, 1,0, 0,1, Tc, clRed);
- •Var I : word;
- •Var dx : real; tr : trPoint; tp: tPoint; I : word;
- •Inherited Init(fx0, fy0, fmx, fcnv);
- •Var dx : real;
- •Var t : array[1..3] of tPoint; tr : trPoint;
- •I : byte;
- •Var dx : real;
- •Var list : cList;
- •Var I : word;
Var a, b, X, dx, y1, y2, s1, s2 : real;
n, i : word;
BEGIN
a:=0; b:=Pi; n:=100;
// Начало цикла суммирования
dx:=(b-a)/n; s1:=0; s2:=0;
for i:=1 to n do
begin
x:=a+dx*(i-1);
y1:=y(x);
y2:=y(x+dx);
if y2>y1
then // Функция возрастает
begin s1:=s1+dx*y1;
s2:=s2+dx*y2; end
else // Функция не возрастает или убывает
begin s2:=s2+dx*y1;
s1:=s1+dx*y2; end;
end;
// Окончание цикла суммирования
writeln(s1:7:4, s2:7:4); // 1.9684 2.0313
readln;
END.
Этап 2. После отладки программы с циклом суммирования при заданном числе разбиений, можно переходить к программированию внешнего цикла по точности. В приведенном ниже листинге текст цикла суммирования опущен. Функциональную часть цикла, которая на листинге выше выделена курсивом, необходимо вставить в указанное место. Управление точностью производится за счет увеличения числа разбиений в два раза за одну итерацию. Как и в предыдущих программах, выход из цикла при достижении заданной точности eps производится с помощью процедуры break, а условием прекращения цикла является превышение максимального числа итераций NIterMax. Обратите внимание на замену типа целочисленных переменных с word на longword, поскольку число разбиений n может быть очень большим.
Листинг 7.1б. Цикл по точности. Заголовок программы и раздел описаний P&F с функцией y(x) не приводятся.
Const NIterMax=10000;
eps=0.0001;
Var a, b, X, dx, y1, y2, s1, s2 : real;
n, i, iter : longword;
BEGIN
a:=0; b:=Pi;
n:=10; iter:=0;
repeat
// Текст цикла суммирования из листинга 7.1а
if abs(s1-s2)<eps then break;
n:=2*n; // Увеличение числа разбиений
Inc(iter);
until iter > NIterMax;
writeln(s1:9:5, s2:9:5); // 1.99996 2.00004
writeln(' iter=', iter); // 13
readln;
END.
Задания.
Преобразовать алгоритм вычисления площади под кривой в функцию, возвращающую значение 0.5*(s1+s2) с интерфейсом
Function Sq(a,b,eps:real; Var s1, s2:real):real;
Значения s1, s2 являются выходными и возвращаются через список параметров. Диапазон a,b и точность eps являются входными параметрами.
С использованием функции Sq составить программу вычисления площади под кривой y=abs(f(x)) с точностью eps=0.001. Функцию f(x)и значения a,b взять для своего варианта в задании к первой части Практикума 6 «Решение нелинейных алгебраических уравнений». Вывести значения площади и отдельно площадей s1 и s2. Вывод результатов выполнять только в основной программе. При необходимости можно использовать вывод диагностических сообщений из процедур и функций.
Процедурные типы.
После того, как предыдущее задание будет выполнено, у тех, кто это сделал самостоятельно, возникнет вполне законный вопрос №1, а у тех, кто этого не сделал – вполне понятное желание №2.
Между тем, получение ответа на вопрос №1 и есть предпосылка для выполнения желания №2.
Итак, вопрос №1. Можно смириться с тем, что для вычисления площади под кривой, заданной другой функцией, например для другого варианта, требуется переписать исходный код глобальной функции y(x). Но, что же делать, если необходимо в одной программе вычислить, площади для нескольких функций? Можно, конечно, создать несколько копий-аналогов функции Sq, отличающихся только именами и используемой глобальной функцией, но тогда желание №2 покажется уж вовсе недостижимым. Для решения этой и подобных проблем в DELPHI существует механизм передачи в функцию вычисления площади любой другой функции, без ее перепрограммирования, получивший название процедурные типы.
Все программные единицы, будь то основная программа, процедура или функция, «живут» в линейной памяти компьютера примерно одинаково: есть область программного кода со своим адресом и есть область данных со своим. Иначе говоря, если мы знаем где, по какому адресу, находится программный код, и знаем где и как устроены данные, т.е. знаем, сколько их, знаем их типы, то этого достаточно.
Таким образом, чтобы передать подпрограмме другую подпрограмму (процедуру или функцию) достаточно сообщить ей две сущности
Адрес начала программного кода.
Шаблон, по которому «скроен» список параметров, т.е. их количество и типы.
Создатели DELPHI сознательно решили скрыть всю эту адресную подоплеку, заменив ее понятием процедурного типа.