
- •1. Основы работы на компьютере
- •1.1. Операционная система ms dos
- •Работа с каталогами
- •Работа с файлами
- •1.2. Программа-оболочка norton commander
- •Работа с каталогами
- •Работа с файлами
- •Управляющее меню программы
- •2. Основы алгоритмизации
- •Основы программирования на turbo pascal
- •Типы данных
- •Программирование разветвляющихся процессов
- •Программирование циклических процессов
- •Работа со сложными типами данных
- •4.1. Массивы
- •4.2. Строки типа string
- •4.3. Множества
- •4.4. Комбинированный тип данных – записи
- •Тема 1. Операционная система ms dos
- •Варианты задания
- •Тема 2. Программы-оболочки
- •Пример выполнения задания
- •Варианты задания
- •Тема 3. Основы алгоритмизации
- •Пример выполнения задания
- •Варианты задания
- •Тема 4. Программирование линейных и разветвляющихся процессов Пример выполнения задания
- •Варианты задания
- •Пример выполнения задания
- •Варианты задания
- •Тема 6. Работа с массивами Пример выполнения задания
- •Варианты задания
- •Тема 7. Записи Пример выполнения задания
- •Варианты задания
- •Библиографический список
- •Приложения
- •Основная таблица кода ascii
- •Альтернативная таблица (коды со 128 по 255)
- •Оглавление
- •1. Основы работы на компьютере ……………………………………….……. 1
- •1.1. Операционная система ms dos ………………………………………… 1
Программирование циклических процессов
Повторяющиеся действия могут быть описаны в программе с помощью операторов цикла, которые имеют разные логические структуры. Таких операторов три: оператор цикла с постусловием, оператор цикла с предусловием и оператор цикла с параметром.
Цикл с постусловием
Если алгоритм допускает сначала выполнение определенного набора действий, а затем проверку некоторого условия на предмет прекращения их повторения, то такой алгоритм должен включать в себя блок цикла с постусловием. Число повторений такого цикла заранее не известно, т.к. зависит от выполнения условия. Если условие выполняется, то прекращаются действия, входящие в тело цикла. В противном случае циклические действия продолжаются.
Описанный алгоритмический блок и соответствующий ему в языке оператор представлены ниже. Служебные слова Repeat (повторять) и Until (до тех пор пока не) по своей сути являются такими же операторными скобками, как begin - end.
REPEAT
<Оператор
1>;
. . . Тело цикла
НЕТ <Оператор N>
ДА UNTIL <Условие выхода из цикла>;
где U - условие прекращения циклических действий.
Пример 3. В последовательности вводимых с клавиатуры символов, заканчивающейся символом ‘!’, подсчитать количество символов ‘a’, пар символов ‘z’, и заменить ‘x’ на ‘y’.
Представим
алгоритм
na := 0, nz := 0, prsym := #1 решения задачи в виде
Ввод
(sym)
структурограммы.
sym
= ‘a’ да
na := na + 1
(sym=’z’)
И
(prsym=’z’)
да нет
nz := nz + 1 prsym := sym
prsym := #1
sym = ‘x’ да
sym := ‘y’
Вывод (sym)
до sym = ‘!’
В ывод (na, nz)
Реализуем приведенный алгоритм в виде программы на Turbo Pascal.
program symbols;
var na : byte; {Количество символов ‘a’}
nz : byte; {Количество пар символов ‘z’}
sym, prsym : char; {Текущий и предыдущий символы}
begin
na:=0; nz:=0; prsym:=#1; {Предыдущий символ имеет № 1 в таблице}
writeln(‘Введите последовательность символов, завершающуюся !’);
repeat {Цикл с постусловием обработки символьных данных}
read(sym); {Ввод символа}
if sym = ‘a’ then na := na + 1; {Подсчет числа символов a}
if (sym =’z’) and (prsym = ‘z’)
then begin nz:=nz+1; prsym := #1 end
else prsym := sym;
if sym = ‘x’ then sym := ‘y’;
write (sym) {Вывод символа на экран}
until sym = ‘!’; {Конец цикла обработки символов}
writeln;
writeln(‘Количество символов a в строке = ’, na);
writeln(‘Количество пар символов z = ’, nz)
end.
Рассматриваемый цикл с постусловием применим для решения широкого круга задач: нахождение бесконечных сумм и произведений, уточнение корней нелинейных алгебраических уравнений, табулирование функций и др. Приведем еще один пример на использование оператора repeat - until.
Пример
4. Уточнить методом половинного деления
(дихотомии) с погрешностью 0,001 на отрезке
[0, 2] корень уравнения f(x)
= 0, где
.
Составим алгоритм решения задачи. В качестве отправной точки на заданном интервале [a; b] выберем точку в середине отрезка. Выясняем, на какой из двух половинок отрезка функция меняет знак, а значит, имеет корень. Эта половина и становится новым отрезком ab, подлежащим очередному делению пополам. Переопределение отрезка производят за счет изменения одной из его границ. Процесс продолжается до тех пор, пока не выполнится условие окончания цикла - | f(x) | < 0,001.
Начало
Ввод (a,b,e) a
x:=(a+b)/2, y:=f(a), z:=f(x) Вывод (x, f(x))
yz<0 Конец
нет
|f(x)|<e
да
a
program dihotomia;
const e = 0.001;
var a,b,x,y,z : real;
begin
writeln(‘Введите левую и правую границы отрезка’); readln(a,b);
repeat
x := (a + b)/2;
y := a*a - 2; z := x*x - 2;
if y*z < 0 then b := x else a := x
until abs(x*x - 2) < e;
writeln(‘Корень = ‘, x);
writeln(‘Значение функции в этой точке = ‘, x*x -2)
end.
Цикл с параметром
Конструкция данного цикла предназначена для организации повторяющихся действий (вычислений) при заранее известном числе повторений тела цикла. Блок и реализующий его оператор языка представлены ниже.
Вариант
1
Тело цикла
p:=n(h)k
FOR
p:=n TO k DO <Оператор>;
Вариант 2
FOR p:=n DOWNTO k DO <Оператор>;
Оператор FOR имеет два варианта написания в зависимости от того, как соотносятся начальное n и конечное k значения параметра цикла p. В первом варианте параметр изменяется от меньшего значения n до большего k, во втором - от большего n до меньшего k. Отсюда и различие в служебных словах. Шаг h, с которым автоматически изменяется параметр после выполнения тела цикла (оператора), зависит от типа переменной, используемой в качестве параметра цикла. Тип переменной может быть любым порядковым. Параметр p увеличивает на единицу порядковый номер своего следующего значения в варианте 1, а в варианте 2 - уменьшает на единицу. Величины n и k могут быть представлены выражениями соответствующего параметру p типа. В теле допускается использовать любой оператор языка, в том числе и пустой оператор, обозначаемый ; (точка с запятой). Запрещается вхождение в оператор FOR извне. Такую потенциальную возможность предоставляет оператор безусловного перехода GOTO. Данный оператор не отвечает духу структурного программирования и используется редко. Формат его использования: Goto <Метка>;. С помощью данного оператора нельзя также переходить из основной программы в подпрограмму и наоборот. Метка должна быть описана в разделе Label объявления меток с помощью имени языка или целого числа без знака от 0 до 9999 следующим образом:
Label a1, 45, 01;
Не следует также переопределять параметр p в теле цикла For, для этого служит заголовок цикла.
Пример 5. Вывести на экран буквы латинского алфавита в обратном порядке через пробел.
program bukva;
var c:char;
begin
for c := ‘z’ downto ‘a’ do write(c, ‘ ‘);
writeln end.
Широкое распространение табличного представления значений различных функций позволяет говорить о необходимости уметь программировать процесс получения этих значений, отстоящих друг от друга на некоторый шаг в направлении изменения аргумента. Чтобы воспользоваться циклом со счетчиком, требуется осуществить переход от вещественных аргумента и шага к целочисленному параметру цикла, изменяющемуся с единичным шагом. Покажем реализацию такого приема на примере.
П
ример
6. Пусть необходимо протабулировать с
шагом h
для аргумента, изменяющегося от xn
до xk,
функцию f(x)
= sin(x)/x.
Подсчитаем количество значений аргумента
n,
для которых требуется определить
значение функции:
.
Здесь запись ]число[
обозначает
целую часть числа. Тогда можно представить
алгоритм решения задачи и соответствующую
ему программу в следующем виде.
Ввод (xn, xk, h)
x := xn
n := ](xk-xn)/h[ + 1
i := 1 (1) n
f := sin(x)/x
Вывод (x, f)
x := x + h
program tab_fun;
var xn, xk, x, h, fun : real;
i, n : byte;
begin
writeln(‘Введите начальное и конечное значения аргумента, шаг’);
readln(xn, xk, h);
x := xn; n := trunc((xk-xn)/h) + 1;
for i := 1 to n do
begin
fun := sin(x)/x;
writeln(‘x = ’, x:4:2, ‘ fun = ‘, fun:7:4); {форматный вывод}
x := x + h
end {for} end.
Версия Turbo Pascal 7.0 включает в себя процедуру Break досрочного выхода из цикла с любой организацией, в том числе и из цикла с параметром. Рассмотрим на примере возможности ее использования.
Пример
7. С погрешностью 0.001 уточнить на отрезке
[2, 3] методом касательных (Ньютона) корень
уравнения
.
Задают начальное приближение к корню
,
а затем применяют формулу метода с
использованием производной для отыскания
очередного приближения:
.
Если |
-
|
< 0,001, то найденное приближение и есть
корень с заданной погрешностью. Ниже
приводится программная реализация
метода с помощью цикла с параметром.
program newton;
const e = 0.001;
n = 50; {Число повторений цикла с запасом}
var a, b, d, q : real;
i : byte;
begin
writeln(‘Введите границы отрезка a и b’);
readln(a,b);
q := (a + b)/2; {Начальное приближение}
for i := 1 to n do
begin
d := (exp(q)-q*q-10)/(exp(q)-2*q);
q := q - d;
if abs(d) < e then begin
writeln(‘Корень уравнения = ‘, q);
break end {if}
end; {for}
writeln(‘Значение функции при этом = ‘, exp(q)-q*q-10)
end.
В состав процедур Turbo Pascal 7.0 включена процедура Continue, позволяющая переходить к очередной итерации цикла без завершения выполнения предыдущей. Часть тела цикла, следующая за обращением к процедуре, не выполняется. Таким образом можно, например, реализовать цикл с параметром, который изменяется с шагом, отличным от единицы.
Пример 8. Подсчитать сумму четных чисел в диапазоне от n до k.
program Summa_Chotny;
В
вод
(n, k) var i,n,k : byte;
n
- нечетное?
sum : word;
ДА begin
n := n+1 writeln(‘Введите n и k’);
s um := 0 readln(n,k); sum := 0;
i := n (2) k
if odd(n) then n := n+1;
sum := sum + i for i := n to k do begin
В ывод (sum) if odd(i) then continue;
sum := sum + i end;
writeln(sum) end.
Форматный вывод данных
При выводе данных среда ориентирована на их стандартное представление на экране. Оно предполагает выделение под каждый символ одной позиции, под целое число – столько позиций, сколько цифр в числе плюс позиция под знак. Вещественные выводятся с указанием мантиссы и порядка. Программист может задать нужный ему формат вывода данных. Если при этом он укажет недостаточное число позиций, то среда дополнит их до требуемого количества. Количество отводимых на тот или иной элемент вывода позиций задается через двоеточие, например writeln(k:6, n div 3:4, ‘text’:10). Тем самым под значение переменной k отводится 6 позиций, под выражение n div 3 – 4, а под text – 10. Для вещественных задают сначала общее число позиций, а затем – на дробную часть, например writeln(z:8:5).
Цикл с предусловием
Рассмотрим названный цикл в связи с определенными действиями. В вычислительной практике часто приходится иметь дело с повторяющимися вычислениями, результаты которых на очередном витке цикла зависят от результатов вычислений на предшествующем витке. Подобные вычисления называют итерационными, а очередное повторение тела цикла - итерацией. Примерами таких вычислений являются: уточнение с заданной погрешностью корней уравнений, нахождение бесконечных сумм и произведений, численное интегрирование и др. В качестве условия прекращения таких вычислений становится достижение требуемой погрешности. Рассмотрим некоторые частные случаи итерационных вычислений.
Сумма бесконечного ряда
Пусть
требуется определить с абсолютной
погрешностью
сумму
бесконечного ряда
.
Если существует некоторое число S,
к которому стремится предел указанной
суммы при числе слагаемых n,
стремящемся к бесконечности, то говорят,
что ряд сходится к S.
Выражение
описывает общий член ряда. Процесс
вычисления суммы ряда сводится к
циклическому выполнению двух действий:
получению на основании
очередного слагаемого и добавлению его
к сумме. Вычисления завершаются, когда
очередное слагаемое становится меньше
заданной погрешности :
.
(1)
Прекращение суммирования по условию (1) гарантирует погрешность не выше заданной в случае знакопеременного ряда. Если же ряд является знакопостоянным, то выполнение условия не гарантирует заданной погрешности, т.к. сумма отбрасываемых (из-за их малости) членов ряда может превысить .
Запись
выражения для
на языке Turbo
Pascal
обычно не вызывает затруднений. Однако
есть частные случаи, когда выражение
для
содержит целые степени аргумента x
и факториалы.
В этих случаях применяют следующий
прием. Вычисляют очередное слагаемое
или его часть
как функцию от предыдущего выражения:
или
,
(2)
где
.
(3)
Ниже
приведен алгоритм нахождения суммы
бесконечного ряда с использованием
вспомогательной функции
для конкретного примера.
Пример 9. Вычислить с погрешностью =0,001 для заданного значения аргумента x значение функции ln(x) с помощью ее разложения в ряд:
(0
< x
≤ 2).
Выразим
вспомогательную для части
слагаемого
функцию
из выражения (3)
.
С ее помощью по формуле (2) будем определять
очередное значение
.
Первый член ряда находим непосредственно
из формулы для общего члена ряда,
подставив в нее n
= 1,
- (x-1).
Ниже приведен алгоритм решения задачи.
Ввод
(x, )
summa:= 0; t:= x - 1; n:= 1; sl:= t/n
Пока
summa:= summa + sl
:=
-(x - 1); t:= t
n:= n + 1; sl := t/n
Вывод ( summa, ln(x) )
Запишем алгоритм на языке программирования:
program Summa_Ryada;
const e = 0.001;
var
n: byte;
fi, sl, summa, t, x: real;
begin
writeln(‘Введите x’); readln(x);
summa:=0; t:=x - 1; n:=1; sl := t/n;
while abs(sl) > e do begin
summa:=summa + sl;
fi:= - (x – 1); t:=t*fi;
n:=n + 1; sl := t/n
end; {while}
writeln(‘Сумма ряда = ‘, summa);
writeln(‘Учтено ‘, n-1, ‘ слагаемых’);
writeln(‘Синус = ‘, ln(x)) end.
Бесконечное произведение
Бесконечное произведение представляет собой произведение бесконечного числа сомножителей:
.
Если
такое произведение стремится при i
к некоторому пределу P,
то P
называют значением бесконечного
произведения. Если P
конечно и отлично от нуля, то произведение
называется сходящимся, в противном
случае - расходящимся. Если бесконечное
произведение сходится, то
.
Именно это обстоятельство можно
использовать для прекращения циклических
вычислений частичных произведений, а
точнее, когда очередной сомножитель
станет отличаться от 1 на величину меньше
заданной погрешности .
Разберем правила решения данной задачи
на конкретном примере.
Пример
10. С погрешностью 0,0001 вычислить значение
числа
с использованием формулы Валлиса:
.
Ввод
()
p:= 1; m:= 4/3; n:= 2
Пока m-1 >
p:= p*m
m:= 4n*n/(4n*n-1); n := n + 1
Вывод (2*p)
В соответствии с приведенным выше алгоритмом имеем:
program Vallis;
const e = 0.0001;
var
n: byte;
p, m: real;
begin
p:= 1; m:= 4/3; n:= 2;
while m-1 > e do begin
p:= p*m;
m:= 4*n*n/(4*n*n - 1);
end; {while}
writeln(‘Число ПИ = ‘, p*2);
writeln(‘Учтено ’,n-1, ‘ сомножителей’)
end.
Уточнение корня уравнения
Пусть в результате отделения корней стал известен отрезок [a, b], на котором функция f(x) имеет единственный корень. Требуется уточнить его значение с погрешностью . Выберем для решения данной задачи метод хорд. Задаем начальное приближение, например x = a. Хордой соединяем точки кривой на границах отрезка ab:
Ввод
(a, b, e)
[y - f(x)]/[f(b) - f(a)] =
x:= a = (x - a)/(b - a).
Пока
|f(x)|
> e Отсюда точка
пересечения
y:= f(a); z:= f(b); хорды с осью абсцисс:
x = a - f(a)(b - a)/[f(b) - f(a)]; w:=f(x) x = a - f(a)(b - a)/[f(b) - f(a)].
yw
< 0
ДА НЕТ Это очередное приближение.
b:= x a:= x Переопределяем отрезок ab.
Вывод (x, f(x))
Применим
приведенный выше алгоритм для уточнения
корня уравнения
с погрешностью 0,0001
на
отрезке
[0, 2] .
program Horda;
const e = 0.0001;
var
n: byte;
a, b, w, x, y, z: real;
begin
writeln(‘Введите границы отрезка’);
readln(a,b);
x:= a; n:= 0;
while abs(x*x-1) > e do begin
y:= a*a-1; z:= x*x-1;
x:=a - y*(b - a)/(z - y); w:= x*x -1;
if y*w < 0 then b:= x else a:= x;
n:= n + 1 end;
writeln(‘Корень уравнения = ’, x);
writeln(‘Значение функции в этой точке = ’, x*x-1)
writeln(‘Число итераций: ’,n)
end.
Вложенные циклы
В вычислительной математике весьма распространены задачи, связанные с выполнением повторяющихся действий внутри другого циклического процесса. Примерами таких вычислений являются: численное интегрирование с заданной погрешностью, табулирование функций нескольких переменных, расчет двойных сумм и произведений и т.п. Вычислительный процесс при решении подобных задач организован так, что структура внутреннего цикла оказывается вложенной в конструкцию внешнего цикла. При этом наиболее быстро изменяется параметр внутреннего цикла, т.к. он должен принять все свои значения при одном значении параметра внешнего цикла. Можно говорить об уровнях вложения циклов друг в друга: нулевой, первый, второй и т.д. Принципиального ограничения на глубину вложения нет, причем на любом уровне может быть использован любой из циклов. Рассмотрим организацию сложных циклических вычислений на конкретных примерах.
Пример
11. Для x,
изменяющегося с шагом h
= 0,1 в диапазоне [-0,5; 0,5], вычислить y
= ln(1-x),
если x
0, и y
= ln(1
+ x),
если x
> 0. При этом ln(1-x)
вычислять как сумму ряда:
.
Начало
Ввод (h)
x:= - 0.5
ДА
x 0
НЕТ s:= 0; z:= 1
y:= ln(1 + x) n:= 1(1)50
z:= z*x; s:= s + z/n y:= - s
Вывод (x, y)
x:= x + h
НЕТ
x > 0.5
ДА
Конец
В
приведенной выше блок-схеме алгоритма
s
обозначает сумму ряда, а переменная z
хранит значения
.
Реализуем данный алгоритм в системе
программирования Turbo
Pascal:
program Vlog_Cicl;
const h = 0.1;
var
n: byte;
s, x, y, z: real;
begin
x:= - 0.5;
repeat {Внешний цикл}
if x <= 0 then begin
s:= 0; z:= 1;
for n:= 1 to 50 do begin
z:= z*x;
s:= s + z/n end; {for}
y:= - s end {then}
else y:= ln(1 + x);
writeln(‘x = ’, x:4:1, ‘ y = ’, y:6:4); x:= x + h
until x > 0.5 end.
Пример
12. С погрешностью 0,001
вычислить по методу прямоугольников
.
Метод прямоугольников является простейшим численным методом вычисления определенных интегралов. Подынтегральная функция f(x) заменяется полиномом нулевого порядка, который строится на заданном множестве точек. Точки могут располагаться как через равные интервалы, так и через неравные. В результате площадь под кривой f(x) (геометрическая интерпретация интеграла) заменяется при расчете суммой площадей отдельных прямоугольников. На рисунке показан интервал интегрирования ab, разбитый на равновеликие отрезки, служащие основанием таких прямоугольников.
Площадь
i
-го прямоугольника:
f(x)
,
1
i
n.
При количестве прямоугольников n имеем:
.
a
b x
При
h
= (b
- a)/n
численное значение интеграла
.
(*)
Формула (*) позволяет вычислять интеграл с погрешностью, зависящей от числа отрезков разбиения n. Чтобы вычисление происходило с заданной погрешностью, следует организовать итерационный процесс. Он должен начинаться с вычисления значения I по формуле (*), например при n=2. Затем удваивают n и вычисляют новое численное значение интеграла. Сравнивают разницу между двумя этими значениями интеграла с заданной погрешностью. Процесс продолжается до достижения заданной погрешности.
Метод прямоугольников имеет модификацию - метод средних. Кроме этих двух методов используют более эффективные методы: трапеций, Симпсона, Гаусса и др.
Ниже приведена структурограмма алгоритма метода прямоугольников. В ней приняты следующие обозначения: j1 - текущее значение интеграла, j2 - значение интеграла при вдвое меньшем числе прямоугольников n.
Ввод
(a, b, )
n:= 2; j1:= 0
j2:= j1;
h:= (b-a)/n; x:= a; s:= 0
i:= 1(1)n
s:= s + sin(x)/x; x:= x + h
j1:= s*h; n:= n*2
до |j1 - j2| <
Вывод (j1)
Этому алгоритму соответствует следующая программа.
program Method_Prm;
const e = 0.001;
var i, n: word;
a, b, j1, j2, h, s, x: real;
begin
writeln(‘Введите пределы интегрирования a и b’); readln(a, b);
n:= 2; j1:= 0;
repeat
j2:= j1; h:= (b - a)/n; x:= a; s:= 0;
for i:= 1 to n do begin
s:= s + sin(x)/x; x:= x + h end;
j1:= s*h; n:= n*2
until abs(j1 - j2);
writeln(‘Интеграл = ’, j1) end.