Алгоритмический язык Турбо-Паскаль

Анализ сущности программирования, которое заключается в записи алгоритма на языке программирования и отладке программы. Ознакомление со структурой языка Турбо-Паскаль. Изучение понятия файла - именованной области внешней памяти персонального компьютера.

Рубрика Программирование, компьютеры и кибернетика
Вид дипломная работа
Язык русский
Дата добавления 06.10.2017
Размер файла 124,4 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Циклы с условием обычно используются в тех случаях, если количество повторений блока операторов заранее не известно, например, при расчете суммы членов бесконечного ряда с заданной погрешностью.

Сумма членов бесконечной последовательности a1, a2, a3, aN, называется бесконечным рядом и записывается в виде:

a1 + a2 + a3 +. . . + aN+. . . .

Здесь aN - общий член ряда. Сумма конечного числа членов ряда называется частичной суммой и обозначается " SN ". Если сумма членов бесконечного ряда имеет конечный предел "S", то ряд называется сходящимся. Для некоторых рядов получены формулы расчета суммы членов ряда. Например, сумма членов числового ряда:

1 + 1/32 + 1/52 + . . . + 1/(2*N-1)2 + . . . имеет предел S = Pi2/8;

и общий член aN= 1/(2*N-1)2, где N = 1, 2, 3, .. .

Для сходящегося ряда вычисляется последовательность частичных сумм с заданной погрешностью. Абсолютная погрешность расчетов определяется по формуле Eps=abs(S-SN), либо Eps=abs(aN), если значение S неизвестно. Относительная погрешность расчетов определяется по формуле Eps_o=abs((S-SN)/S), либо Eps_o=abs(aN/SN). Частичные суммы вычисляются по формуле: SN = SN-1 + aN;

Для знакопеременного ряда следует добавить k1=-1, а в цикле: k1:=-k1, aN=k1*aN. В некоторых случаях "N"-ый член ряда выражается через "N-1"-ый, например, для ряда:

1 + 1/2! + 1/4! + 1/6! + . . . + 1/(2*N)! + . . . ; N = 0, 1, 2,

общий член ряда вычисляется по формуле: aN = aN-1*k;

Параметр k = aN/aN-1; - коэффициент роста вычисляется предварительно (до написания программы). Для данного ряда

aN = 1/(2* N )! = 1/( 1*2*. . . *(2*N-2)*(2*N-1)*2*N);

aN-1 = 1/(2*(N-1))!= 1/((2*N-2))!= 1/(1*2*. . . *(2*N-2));

k = aN/aN-1 = 1/((2*N-1)*2*N).

Здесь N! = 1*2*3*. . . *N; - вычисление факториала числа "N", причем 0! = 1.

Расчет частичных сумм производится в цикле с условием, например, для данного ряда операторами:

N:= 0; a:= 1; SN:= 1; e:= 2. 7182828; S:= (e2 + 1)/e;

repeat N:= N+1; k:= 1/((2*N-1)*2*N); a:= a*k;

SN:= SN+a;

Writeln('Частичная сумма Sn=', Sn:-11:6, '_ _ n=', n:2);

until abs(S-Sn) < eps; { eps - допустимая погрешность расчетов}

Writeln('_ _ _ Сумма ряда S =', S :-11:6);

1.7.6 Операторы ограничения и прерывания цикла

Данные операторы применяются внутри операторов цикла с параметром или условием. Операторы имеют вид:

Continue; - ограничение цикла,

Break; - прерывание цикла.

Операторы Continue; и Break; позволяют производить действия не для всех операторов внутри цикла. Действие оператора Continue; заключается в передаче управления на начало цикла, при этом контролируется условие выхода из цикла. Действие оператора Break; заключается в передаче управления оператору, следующему за последним оператором цикла, при этом не контролируется условие выхода из цикла. Во вложенных циклах операторы Continue; и Break; действуют только на цикл в котором они записаны. Приведем пример использования операторов для блокировки несанкционированного доступа в программу.

For i:= 1 to 3 do begin

Write( 'Введите ПАРОЛЬ:' ); Readln(S); {S и Parol - переменные одного типа}

If S = Parol Then Break { прерывание цикла }

else If i <> 3 Then Continue; { ограничение цикла }

Writeln( 'Доступ к программе ЗАПРЕЩЕН' );

Writeln( 'Нажмите Enter' ); Readln; Halt { прерывание программы }

end; { продолжение программы }

1.7.7 Оператор перехода к метке

Оператор перехода служит для передачи управления помеченному оператору и имеет вид:

Goto "метка";

Меткой может быть целое положительное число или идентификатор. Меткой помечается оператор, которому передается управление, например:

M1: Write('Введите x>=0'); Readln(x); If x<0 Then Goto M1;

Метки описываются в разделе описания, например: Label M1;

Метка не может стоять перед оператором Begin end;

Следует избегать переходов внутрь операторов цикла.

Оператор перехода часто применяется для "досрочного" выхода из операторов цикла. Приведем пример операторов для расчета конечной суммы вклада через 10 месяцев (pr - процентная ставка), при условии досрочного снятия вклада, если начальная сумма "S1" возросла более чем в два раза:

S:= S1; For i:= 1 to 10 do begin

S:= S*(1 + pr/100); If S > 2*S1 Then Goto M1 end;

M1: Writeln(S);

Приведем пример программы расчета наибольшего общего делителя двух натуральных чисел по алгоритму Евклида: наибольший общий делитель натуральных чисел "а" и "в" равен наибольшему общему делителю меньшего из чисел ("a" или "b") и остатка от деления большего числа на меньшее.

PROGRAM del;

label M1, M2, M3;

var b, a: longint;

Begin

M3: Writeln('Введите два натуральных числа'); readln(a, b);

Writeln; if (a <= 0) or (b <= 0) then goto M3;

{------------------------------------------------ алгоритм -1 -------------------------------------------------}

M1: if a = b then Writeln('наибольший делитель =', a) else

begin if a > b then a:= a-b else b:= b-a;

goto M1 end; Writeln;

{ ---------------------------------------------- алгоритм -2 ------------------------------------------------}

M2: if a > b then a:= a mod b else b:= b mod a;

if (a= 0) or (b= 0) then Writeln('наибольший делитель =',a+b)

else goto M2;

Writeln('Нажмите Enter'); readln;

end.

1.8 Блок-схемы алгоритмов

При обучении программированию используется графическое описание алгоритма решения задачи в виде блок - схемы. Такое представление алгоритма достаточно удобно и наглядно показывает последовательность выполнения операторов программы.

В соответствии с используемыми в программе операторами различают следующие типы алгоритмов: линейный, ветвящийся, циклический, комбинированный. Приведем пример блок - схемы комбинированного алгоритма для расчета суммы положительных S1 и отрицательных S2 чисел из N случайных чисел от -100 до 100.

Соответствующие алгоритму операторы имеют вид:

Begin Randomize;

Writeln('Введите количество случайных чисел'); Readln(N);

S1:=0; S2:=0;

For i:=1 to N do begin x:=Random(201)-100;

if x<0 Then S2:=S2+x else S1:=S1+x end;

Writeln('S1= ', S1, ' S2= ', S2); Readln

End.

1.9 Составление диалоговых программ

Диалоговый режим работы программы заключается в диалоге пользователя с программой в соответствии с запрограммированной схемой возможных вариантов. Во время выполнения программы происходит запрос к пользователю ввести дополнительные данные, определяющие дальнейшую работу программы. Приведем пример программы угадывания случайно выбранного числа в интервале от 5 до 16 с пяти попыток.

PROGRAM NUMBER; { угадать случайное число }

Var I, N, N1: integer;

BEGIN

Randomize; N1:= Random(12) + 5;

for i:= 1 to 5 do begin

Write('угадайте число от 5 до 16 N='); readln(N);

IF N<>N1 then begin Writeln('не угадал');

Writeln('осталось ', 5-i, ' попыток') end

else begin Writeln('угадал'); Writeln('Нажмите Enter');

readln; Halt end

end; Writeln('Нажмите Enter'); readln;

END.

Определение формулы для "N1" производится по следующему алгоритму. Пусть дано N_Min и N_Max - интервал изменения N1, тогда случайное значение

N1:= Random(A) + B; где B:= N_Min; A:= N_Max - N_Min + 1;

1.10 Линейные массивы

Массив - упорядоченные данные одного типа. Возможно создание массива, включающего массив другого типа. Массивом часто обозначают характеристики обьектов одного типа, имеющих одинаковые единицы измерения. Массив состоит из элементов, имеющих порядковые номера, т. е. элементы массива упорядоченны. Таким образом, если обьекты одного типа обозначить именем, например "A", то элементы обьекта будут A[1], A[2] и т. д. В квадратных скобках указан номер элемента. Порядковый номер элемента массива, обычно не несет никакой информации о значении элемента, а показывает расположение элемента среди других. К элементам массива можно обращаться только по их номеру (индексу). Значения элементам массива присваиваются также как и другим переменным с учетом типа массива. Если элементы массива имеют один индекс, то массив называется одномерным или линейным, либо массив - вектор. Значения элементов одномерного массива обычно выводят на экран или бумагу в виде столбца или строки. В некоторых случаях удобно элементы массива пронумеровывать двуми независимыми индексами, такие массивы называются двумерными или матрицами. Значения элементов двумерного массива обычно выводят на экран в виде таблицы. Если элементы массива имеют три независимых индекса, то массив называется трехмерным. Значения элементов трехмерного массива обычно выводят на экран в виде набора таблиц.

Линейным массивом можно обозначить, например, оценки учеников класса. Каждая оценка является значением элемента массива оценок "A" и имеет порядковый номер (индекс). В Турбо-Паскале значение индекса указывается в квадратных скобках после имени массива. Можно создать массив фамилий "S" учеников класса. Значением элемента массива будет фамилия ученика, а индексом - порядковый номер по списку. Пусть дан список фамилий учеников и их оценки:

Если известна зависимость, по которой изменяются значения элементов массива, то присвоение значений удобно проводить в операторах цикла c параметром или с условием. Например, присвоим значения элементам массива "y" по зависимости: y=sin(x), где x= Pi * i/180, 0<= i <=180. For i:= 0 to 180 Do y[i]:= sin(Pi * i/180);

Присвоим случайные значения в диапазоне от -30 до +40 ста элементам массива "R":

Randomize; for i:= 1 to 100 Do R[i]:= - 30 + Random(71);

Присвоим значения семи элементам массива "A" оператором Readln:

For i:= 1 to 7 Do begin Write( ' Введите A[ ' , i , ' ] = ' ); Readln( A [ i ] ) end;

При выводе массива на экран удобно размещать данные в виде таблицы - в несколько колонок. Для вывода обозначений переменных ("шапки таблицы") можно использовать операторы вывода символов в цикле, например:

For j:=1 to 66 do Write('-'); Writeln;

For j:=1 to 3 do Write('_ _ Фамилия _ _ _ оценка _'); Writeln;

For j:=1 to 66 do Write('-'); Writeln;

- шапка для вывода в три пары колонок значений переменных "S" и "A". Шапка занимает 66 позиций (по ширине экрана в текстовом режиме размещается 79 символов и пробел). Оператор Writeln; переводит курсор на новую строчку.

Вывод значений ста элементов массивов "S" и "A" в три пары колонок, произведем операторами:

For i:= 1 to 100 do begin Write('', s[i]:11,'', a[i]:8, '');

if (i mod 3) = 0 Then Writeln;

if (i mod 60) = 0 then readln end;

В этом случае данные таблицы полностью не умещаются на экране и можно задержать прокрутку экрана при выводе данных, применяя оператор Readln после вывода, например, 20 строк.

В цикле удобно определять сумму элементов массива, наибольший (наименьший) элемент и создавать новые массивы, удовлетворяющие некоторому условию, например:

s:= 0; for i:= 1 to 100 do s:= s + a[i]; { s - сумма элементов массива }

a_max:= a[1]; for i:= 1 to 100 do { поиск наибольшего элемента a[j] }

if a[i] > a_max then begin a_max:= a[i]; j:= i end;

j:= 0; k:= 0;

for i:=1 to 100 do {создание новых массивов с элементами: b[j] >=0, c[k] <0}

if a[i] >= 0 then begin j:= j+1; b[j]:= a[i] end

else begin k:= k+1; c[k]:= a[i] end;

j:= 0; k:= 8;

for i:= 1 to 100 do {создание массива номеров "M" для элементов: a[i] > a[k]}

if a[i] > a[k] then begin j:= j+1; M[j]:= i end;

Работа с элементами переменной строкового типа

Переменная строкового типа (String) может рассматриваться как массив элементов символьного типа (Char). Например, если в программе определены переменные

S: string; C: char; и задано S:='Москва', то S[1]='М', S[2]='о' и т. д. и возможно присвоение, например: C:= S[1]; Таким образом строка может рассматриваться как линейный массив символов. Элементы массива, составляющие строку можно переставлять местами и получать новые слова, например:

for i:= 1 to N div 2 do begin C:= S[i]; S[i]:= S[N-i+1]; S[N-i+1]:= C end; Writeln(S);

{ исходное слово выведется справа налево: "авксоМ" }

Здесь N:= ord(S[0]); - число символов в переменной "S" хранится в переменной S[0]. Функция "ord" преобразует символьный тип в целый. N div 2 - количество перестановок для слова из "N" символов. В переменной "C" запоминается значение i-го элемента, который меняется с элементом, симметричным относительно середины строки.

Можно производить поиск и замену заданного символа в строке, например:

for i:=1 to N do if S[i]='_' then writeln('найден символ пробел');

for i:=1 to N do if S[i]='/' then S[i]:='\'; {замена символа "/" на "\"}

Заменяя или переставляя символы в строке по определенной схеме (закону) можно зашифровать строку. Для дешифровки используется, как правило, схема обратной перестановки или замены символов. Например:

for i:=1 to N do S[i]:= chr(ord(S[i])+2); {преобразование исходных символов в символы с кодом большим на две единицы}

Напомним, что все используемые в MS-DOS символы имеют ASCII коды от 0 до 255.

Здесь удобно также использовать функции Pred(C); и Succ(C);

Двумерные массивы

Массивы, рассмотренные выше, имеют элементы, упорядоченные по одному индексу и называются одномерными массивами или векторами. Массив может быть двумерным, трехмерным и т. д. Двумерные массивы имеют элементы, упорядоченные по двум индексам и часто называются матрицами. В Турбо-Паскале при описании многомерного массива диапазоны изменения индексов перечисляются через запятые, например:

Var A: array[1..30, 1..7] of byte;

Рассмотрим пример работы с двумерными массивами.

Обозначим массивом оценки учеников класса по нескольким предметам. Каждая оценка является значением элемента массива оценок "A" и имеет порядковый номер (два индекса). Поставим в соответствие первому индексу номер фамилии в списке учеников, а второму - номер предмета, по которому получена оценка. Тогда двумерный массив оценок можно представить в виде таблицы: каждый элемент a[i, j] находится на пересечении I-ой строки и J-го столбца.

Можно создать одномерные массивы фамилий "S" учеников класса и наименований предметов "P" . Значением элемента массива "Р" будет наименование предмета, а индексом - порядковый номер предмета, например:

1 - физика, 2 - химия, 3 - алгебра, 4 - геометрия, 5 - история, 6 - биология.

Массив оценок можно задать с использованием функции Random, например:

for i:= 1 to N do for j:= 1 to M do A[i, j]:= random(4)+2;

Для вывода наименований предметов ( "шапка" таблицы ) можно использовать операторы:

Writeln;

Write('Фамилия\\Предметы:'); For i:= 1 to M do write(P[i]:9,'_ ');

Для вывода элементов массива "A" на экран удобно использовать вложенный цикл:

for i:= 1 to N do begin writeln; write(S[i]:19, '_ ';

for j:= 1 to M do write(A[i,j]:7, ' _ _ ') end;

Для расчета массива "SS" - сумм "M" элементов в каждой из "N" строк массива "A" (NxM) можно применить операторы:

for i:= 1 to N do begin SS[i]:= 0;

for j:= 1 to M do SS[i]:= SS[i] + A[i, j] end;

Здесь для каждого индекса "i" от 1 до N происходит суммирование элементов A[i, j] по индексу "j" от 1 до M.

При модификации массива "A" изменяется расположение данных в исходном массиве, например, в случае вставки данных из линейного массива "B" в колонку с номером "M1" необходимо сдвинуть данные в колонках J >= M1 используя операторы:

for i:= 1 to N do begin

for j:=M+1 downto M1+1 do A[i,j]:=A[i,j-1]; A[i,M1]:=B[i] end;

Если порядковый номер предмета изменится, то необходимо изменить расположение оценок в массиве "A", например, перестановку колонок с оценками по физике и химии можно сделать операторами:

for j:= 1 to N do begin

a1:=A[1,j]; A[1,j]:=A[2,j]; A[2,j]:=a1 end;

Примечание: при модификации массива "A" не забудьте соответственно изменять расположение данных в сопутствующих массивах, например, "P" или "S".

При создании новых массивов согласно некоторым условиям выбираются данные из элементов исходного массива. Например, для создания массива "В" из четных столбцов массива "A" можно использовать операторы:

for j:= 1 to M do If (j Mod 2) = 0 then

for i:= 1 to N do B[i,j Div 2]:= A[i,j];

Для создания массива "В", состоящего из строк массива "A", удовлетворяющих условию A[i, 1] > C, где C - заданное число, можно использовать операторы:

k:= 0; for i:= 1 to N do If A[i,1] > C then begin

k:= k + 1; for j:= 1 to M do B[k,j]:= A[i,j] end;

Для сравнения значений элементов массива удобно строить столбиковые диаграммы (гистограммы). Например, для вывода "N" значений положительных элементов массива "SS" в виде горизонтальной гистограммы можно использовать операторы:

k:= 30/S_max; { k - нормирующий масштабный коэффициент }

{ S_max - наибольший элемент массива "SS" }

for i:=1 to N do begin writeln; { переход к новому столбику }

yg:=round(k*SS[i]); { yg - длина столбика гистограммы }

for j:=1 to yg do write(#220); { вывод символа с кодом 220 }

end;

Создание баз данных с использованием массивов записей

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

Type Pupil = Record

Fam: String[20]; { Фамилия }

Name: String[10]; { Имя }

Otmetka: array[1..5] of Byte { Отметки по пяти предметам }

end;

Var _10_A, _10_B: array[1..30]of Pupil; {Переменные типа массив записей }

N, i: byte; { N - Число учеников в классе }

Begin N:= 13;

_10_A[1]. Fam:= 'Гришин';

_10_A[1]. Name:= 'Анатолий';

{ и т. д. }

Writeln ('Введите оценки учеников по первому предмету: ');

For i:= 1 to N do begin

With _10_A[i] do Begin

Write(Fam:21, Name:11, '_');

Readln(Otmetka[1])

end

end

end.

{---------------------------------------------------------------- }

Type pupil = Record { массивы в полях записи }

Fam: array[1..30] of String[20]; { Фамилия }

Name: array[1..30] of String[10]; { Имя }

N: Byte; { Число учеников в классе }

Otmetka: array[1..5, 1..30] of Byte { Отметки по пяти предметам }

end;

Var _10_A, _10_B: Pupil; { Переменные типа запись }

i: byte;

Begin

With _10_A do Begin N:= 13;

Fam[1]:= 'Гришин';

Name[1]:= 'Анатолий'; { и т. д. }

Writeln ('Введите оценки учеников по первому предмету: ');

For i:= 1 to N do begin

Write(Fam[i]:21, Name[i]:11,'_');

Readln(Otmetka[1, i])

end

end

end.

Работа с большими массивами

Поскольку суммарный размер всех переменных, описанных в программе, не может превышать длины сегмента ( 64 К ), то использование массивов больших размеров вызывает определенные трудности. Опишем известный способ "разбиения" двумерного массива с использованием переменных типа ссылка.

program Big_Mas;

CONST N1= 30; N2= 50;

type M1= array [1 . . N1 ] of REAL; { тип M1 - массив переменных вещественного типа}

M2= array[1..N2] of ^M1; { тип M2 - массив ссылок на начальные адреса элементов массивов типа M1}

var a1, a2: M2; { двумерные массивы N1xN2 переменных вещественного типа }

i, j: word;

BEGIN

for i:=1 to N2 do New(a1[i]);{ размещение массива в оперативной памяти }

for i:=1 to N2 do New(a2[i]);

for j:= 1 to N1 do

for i:= 1 to N2 do begin

a1[i]^[j]:= j + Sin(Pi*i/N2); { пример расчета значений }

a2[i]^[j]:= j - Cos(Pi*i/N2) { элементов двумерных массивов }

end;

for i:= 1 to N2 do Dispose(a1[i]); { освобождение оперативной памяти }

for i:= 1 to N2 do Dispose(a2[i]);

Readln;

END.

Таким образом в оперативной памяти отводится место не под двумерные массивы "a1" и "a2" размером N1xN2, а под одномерные массивы (размером N2) адресов первых элементов линейных массивов (размером N1). Операция a1[i]^[j] ( a2[i]^[j] ) называется разыменование переменной (элемента массива).

1.11 Текстовые файлы

В прикладных программах, как правило, имеется большое число входных и выходных данных, причем часто возникает необходимость передачи данных из одной программы в другую. Поэтому данные хранятся в файлах и при необходимости считываются, а также записываются в файлы операторами программы. Напомним, что файлом называется именованная область внешней памяти ЭВМ, содержащая различные данные. Доступ к данным в файле может быть прямым или последовательным в зависимости от типа файла. Рассмотрим работу с данными текстовых файлов.

Текстовые файлы представляют совокупность строк переменной длины с последовательным доступом к данным, т. е. данные записываются на диск и считываются только последовательно. Информация в текстовых файлах хранится в символьном (текстовом) виде. При записи числовых или логических значений происходит автоматическое преобразование данных в символьный тип, а при считывании данные автоматически преобразуются в машинные коды. Строки текстового файла заканчиваются символом #13- Enter и #10- возврат каретки. В конце файла устанавливается код #26. При записи в файл данные записываются подряд, а управляющие символы устанавливаются автоматически оператором Writeln. Управляющие символы работают при просмотре/редактировании файла на экране или при печати, но при этом, как правило, не показываются.

Файловая переменная " f " описывается оператором Var f: Text;

В программе файловая переменная " f " связывается с именем файла на диске, оператором:

Assign(f, 'Name_f');

где Name_f - имя файла.

Например, переменная "f" связывается с файлом "file. dat" оператором Assign(f, 'file. dat'); если файл находится в текущем каталоге, иначе к нему указывает дорожка, например: 'C:\Pascal\Work\file.dat'. Связывание файловой переменной "f" с именем файла на диске аналогично присвоению "f" значения.

Для записи данных в файл его необходимо открыть оператором ReWrite(f);

При этом на диске создается новый файл.

Имя файла указано в операторе Assign(f,`Name_f'); Данные записываются в файл оператором Write(f,"сп"); или Writeln(f,"сп"); Причем, оператор Writeln(f,"сп"); устанавливает в конце данных управляющие символы: #13, #10. Здесь обозначено "сп" - список переменных. Повторное применение оператора ReWrite(f); стирает содержимое файла и устанавливает указатель на начало файла.

Для считывания данных из файла его необходимо открыть оператором Reset(f);

При этом указатель устанавливается на начало файла.

Данные считываются с начала файла оператором Read(f, "сп"); или Readln(f, "сп"); Причем, оператор Readln(f, "сп"); после считывания данных для переменных, указанных в "сп" переводит указатель за управляющие символы: #13, #10, игнорируя возможно оставшиеся в строке данные. Следовательно оператор Readln(f); пропускает все данные записанные до управляющих символов #13, #10. Повторное применение оператора Reset(f); устанавливает указатель на начало файла для считывания данных, содержимое файла при этом не меняется.

После окончания работы с файлом его необходимо закрыть процедурой Close(f); иначе файл закрывается автоматически при окончании работы программы, но при этом может произойти потеря данных в конце файла.

Для записи данных в конец закрытого файла применяется процедура Append(f); при этом на диске должен существовать файл с именем, указанным в операторе Assign(f,'Name_f');.

Напомним, что если переменная "f" в операторах ввода/вывода не указывается, то происходит запись данных на экран и считывание данных с клавиатуры с отображением на экране.

Данные, записанные в файл в одной программе часто используются (считываются) в другой программе. При этом данные, записанные в файл операторами Write(f, "сп"); и Writeln(f, "сп");, необходимо считывать соответственно операторами Read(f, "сп"); и Readln(f, "сп"); Причем тип и длина считываемых данных должны соответствовать записанным данным. Если записывать данные подряд (длина записи ограничена длиной сегмента, например до 1024 символов), то при просмотре редактором текста будет выдаваться сообщение об усечении данных по ограничителю длины строки редактора. Рекомендуется в текстовых файлах ограничивать длину строки размерами экрана для удобного просмотра данных. Запись данных в файл позволяет избежать использования массивов, занимающих большую часть оперативной памяти. При этом необходимо сразу после расчета записывать значения переменных в файл. При считывании данных из файла можно использовать массив или переменные того же типа.

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

Приведем примеры операторов записи и считывания данных.

Assign(f1,'File1.dan'); { назначить переменой f1, имя файла: File1. dan}

ReWrite(f1); { открыть файл для записи в первой программе }

Writeln(f1,'Значения "X","Y"' ); { начать запись }

For i:= 1 to N do begin

X:= 0.5*i; Y:= Ln(X); { пример расчета значений переменных }

write(f1, X:6:2, Y:10:4); { записать данные в файл File1. dan }

If i mod 5 = 0 then writeln(f1) { записать символ #13 }

end;

Close (f1); { закрыть файл в первой программе }

Assign(f2,'File1.dan'); {------------------------------------}

Reset(f2); { открыть файл для чтения во второй программе }

Readln(f2); { пропустить первую строчку }

For i:= 1 to N do begin

read(f2, a[i], b[i]); { считать данные в массивы "A" и "B" }

If i mod 5 = 0 then readln(f2) { считать символ #13 }

end;

Close (f2); { закрыть файл во второй программе }

При обновлении файла с выходными данными во время повторных запусков программы на экране появляется предупреждение (Warning) о перезаписи новых данных с диска в оперативную память, т. е. в окно редактора: Reload from disk?, на что следует ответить - Yes.

При работе со строковыми данными необходимо указывать длину переменной типа String в операторе описания типов переменных, иначе оператором Read(f, S); в строковую переменную "S" считывается до 255 символов, а оператором Readln(f, S); считываются все символы до #13, но не более 255, причем пробелы в конце строки игнорируются. Приведем пример программы для считывания строковых и числовых данных из файла и записи их в другой файл.

var c: char; j, i: word;

s: array[1..10] of string[12];

a: array[1..10, 1..6] of word;

f1, f2: text;

BEGIN

assign(f1, 'F1.txt'); reset(f1);

assign(f2, 'F2.txt'); rewrite(f2);

for i:= 1 to 10 do begin read(f1, s[i]); { считывание строки }

for j:= 1 to 6 do read(f1, a[i,j]); { считывание шести чисел }

readln(f1) { считывание символа конца строки }

end;

for c:= 'А' to 'Я' do { цикл по перебору символов }

for i:= 1 to 10 do

if s[i,1] = c then begin

write(f2, s[i]); { запись строк в алфавитном порядке первых символов }

for j:= 1 to 6 do write(f2, a[i,j]:2); { запись шести чисел }

writeln(F2)

end;

close(f1); close(f2);

END.

Здесь полагается что в файле F1. txt записаны данные, которые в редакторе текста имеют вид:

Леонтьев 5 4 4 5 4 3

Ивлев 4 5 3 4 3 4

и т. д.

После считывания данных в программе происходит их сортировка перебором и запись в файл F2. txt в алфавитном порядке первой буквы фамилии.

Примечание: Линейный массив "S" строкового типа можно представить как двумерный массив "S" символьного типа. Здесь первый индекс соответствует номеру элемента одномерного массива "S", а второй - номеру символа в элементе одномерного массива "S". При считывании данных из файла неопределенной длины можно использовать функцию EoF(f); возвращающую признак конца файла, а именно: EoF(f) равен True если указатель стоит на признаке конца файла (код #26), иначе EoF(f) равен False. Приведем пример операторов для считывания текста из файла FF1. t, кодировки текста и записи в файл FF2. t с сохранением кода #13.

assign(f1, 'FF1. t'); reset(f1);

assign(f2, 'FF2. t'); rewrite(f2);

while not EoF(f1) do begin read(f1,c); {считываем переменную типа Char }

if c <> #13 then c:=pred(c); write(f2,c) {кодируем и выводим на экран }

end;

1.12 Разработка функций и процедур

1.12.1 Описание функций и процедур

Практически во всех алгоритмических языках имеется возможность программирования функций и процедур - блоков операторов, оформленных в виде подпрограмм. Разработка функций и процедур необходима при многократном использовании в разных местах программы или в нескольких программах блока операторов, выполняющих однотипные действия, например, расчет значений сложной функции при различных значениях аргумента. В Турбо - Паскале имеется также возможность создавать библиотеки (модули), состоящие из специальных процедур и функций, отличных от поставляемых в пакете ( модули System, Crt, Graph).

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

Заголовок процедуры состоит из служебного слова Procedure, имени процедуры и списка параметров, например:

Procedure Name_P(p1, p2,...: "тип"; Var p3, p4,...: "тип";...);

Заголовок функции состоит из служебного слова Function, имени функции и списка параметров, кроме того указывается тип возвращаемого функцией значения, например:

Function Name_F("список формальных параметров"):"тип результата";

Здесь Function и Procedure - служебные слова,

Name_F, Name_P - имена функции и процедуры соответственно,

p1, p2 - имена формальных параметров-значений,

p3, p4 - имена формальных параметров-переменных,

В дальнейшем, если не оговаривается особо, все сказанное к процедуре относится также и к функции.

Тип возвращаемого функцией значения может быть простым, строковым или типом-указателем. Тип формальных параметров может быть любым, но должен указываться только идентификатором (именем типа). Таким образом, имя типа формального параметра - массива должно быть задано предварительно в операторе Type, например: Type M= array[1..100]of real; Затем тип массива может указываться в заголовке процедуры, например: Procedure Name_P(p: M); Тип формальных параметров описывается только в заголовке процедуры. Список формальных параметров может отсутствовать, например. процедура Randomize; не имеет параметров.

Если в результате выполнения нескольких операторов получается одно значение переменной, то эти операторы можно включить в описание функции. Например, функция Sin(x); возвращает значение, которое присваивается переменной Y:=sin(x); (эта, и другие стандартные функции описаны в модуле System, который подключается к программе автоматически).

Если в результате выполнения нескольких операторов производится некоторое действие или расчет нескольких переменных, то эти операторы лучше включить в описание процедуры. Например, процедура ClrScr; из модуля CRT очищает экран.

Вызов процедуры осуществляется в разделе выполнения основной программы или других процедур (вложенные процедуры). Программа (процедура) внутри которой вызывается другая процедура называется внешней по отношению к вызываемой процедуре.

При вызове процедуры вместо формальных параметров подставляются фактические параметры, значения которых используются в процедуре. Например:

Name_P(p11, p22,..., p33, p44,...); - вызов процедуры Name_P,

Y:= Name_F("список фактических параметров"): - вызов функции Name_F,

Здесь p11, p22, . . . - имена или значения переменных,

p33, p44, . . . - имена переменных, значения которых возвращаются в программу.

Y - переменная, которой присваивается значение возвращаемое функцией.

Типы соответствующих формальных и фактических параметров должны совпадать, а имена могут совпадать или быть различными. Вместо параметров-значений можно подставлять имена переменных, значения переменных или выражения, вместо параметров-переменных подставляются имена переменных. Функция и параметры-переменные возвращают во внешнюю программу значения, полученные после окончания работы функции или процедуры. Изменения параметров-значений в процедуре носит локальный характер, во внешней программе соответствующие фактические параметры не изменяются. Если не требуется передавать во внешнюю программу новые значения, то следует использовать параметры-значения, а не параметры-переменные.

В процедуре можно использовать локальные метки, константы и переменные, описав их в разделе описания процедуры. Локальные имена не должны совпадать с именами формальных параметров, а их значения не передаются во внешнюю программу. Метки, константы и переменные, описанные во внешней программе раньше, чем сама процедура, называются глобальными по отношению к вызываемой процедуре. Если локальные и глобальные имена совпадают, то в процедуре используются локальные значения, а во внешней программе - глобальные значения, т. е. локальные и глобальные идентификаторы независимы. Если имя глобальной переменной уникально (в процедуре не описывается переменная с таким же именем) и ее значение в процедуре изменяется, то оно изменяется и во внешней программе. Вызывая в программе процедуру программист использует ее имя и параметры не анализируя, а часто и не зная содержимого процедуры. Поэтому в целях универсальности процедур следует все значения в процедуру передавать через список параметров, а переменные внутри процедуры описывать, т. е. делать их локальными.

Приведем пример процедуры вывода на экран визитной карточки программиста.

Program NP_1;

Var Dat, Fam: string; { Fam: глобальная переменная }

Procedure VIZ(D_R :string); { D_R - формальный параметр }

Var S_t: string; { S_t: локальная переменная }

Begin Writeln(' -------------------------------------- ');

Writeln(' Разработчик программы:', Fam:14,' ');

Writeln(' ');

Writeln(' г. УФА, ', D_R:14,' ');

Writeln(' Телефон: 22-44-66 ');

Writeln(' -------------------------------------- ');

Write(' Комментарий: '); Readln(S_t)

end;

Begin Fam:='И.И.Иванов'; Dat:='06.12.95';{Dat - фактический параметр }

VIZ(Dat); { вызов процедуры } Readln END.

Если процедура описана в другом файле с именем, например, F_PR. pas, то ее можно подключить к программе, указав в разделе описания директиву: {$I F_PR. pas}

Приведем пример использования стандартных процедур модуля DOS для вывода текущей даты и времени:

uses DOS; { подключение модуля DOS }

Procedure Date_Time;

var y, m, d, d_w:word; h, min, sec, hund: word;{локальные параметры }

begin

GetDate(y,m,d,d_w); {вызов процедуры DOS, возвращающей параметры даты }

GetTime(h,min,sec,hund); { процедура, возвращающая параметры времени }

writeln('сегодня: ' );

writeln('_':10, d, ' число');

writeln('_':10, m, ' месяц');

writeln('_':10, y, ' год' );

writeln('день недели: ', d_w ); { d_w= 0 - воскресенье, и т. д. }

writeln('Время: ' );

writeln('_':6, h, ' часов' );

writeln('_':6, min, ' минут' );

writeln('_':6, sec, ' секунд' ); readln

end;

Begin Date_Time end.

В практических задачах часто пишутся процедуры, возвращающие значения элементов массивов. Приведем пример процедуры расчета "N" значений функции, например, Y= 4*Sin(x)+7*Cos(x); в заданном диапазоне x1<=x<=x2, при N<=100 и равномерной разбивке диапазона.

type r_1000= array[1. . 1000] of real; { задается тип r_1000 }

var Z: r_1000; x1, x2: real; n: word;

Procedure Mas_Y(var Y:r_1000; x1,x2:real; n:word); {Y - параметр-

переменная}

var i: word; x, dx: real; { локальные параметры }

begin

If (n>1000) or (n<2) then begin

writeln('Длина массива >1 и не должна превышать 1000');

Readln; Halt end;

i:=0; x:=x1; dx:=(x2-x1)/(n-1); { dx - шаг изменения аргумента }

If dx<= 0 then begin

writeln('x2 должно быть больше x1'); Readln; Halt end;

While x<x2 do begin

i:= i+1; x:= x1 + dx*(i-1); Y[i]:= 4*Sin(x)+7*cos(x)

end

end;

begin Writeln('Введите значения х1,х2, (x2>x1)'); Readln(x1, x2);

Writeln('Введите значение 1 <n<= 1000 '); Readln(n);

Mas_Y(Z, x1, x2, n); { вызов процедуры, возвращающей массив "Z" }

end.

Здесь тип формального параметра "Y" задается в разделе описания типов внешней программы и совпадает с типом фактического параметра "Z", значения элементов которого возвращаются во внешнюю программу.

Оператор Halt прерывает выполнение всей программы, даже если он используется внутри процедуры. Применение оператора Exit внутри процедуры вызывает прерывание процедуры, но не внешней программы.

Приведем пример процедуры вывода массива чисел в файл:

Type M_30х30_r= array[1..30, 1..30] of real; { задается тип M_30х30_r }

var x: M_30х30_r; i, j, n, m: byte;

{----------------------------------------------------------------}

Procedure Wr_M(a: M_30х30_r; name_f: string; n, m: byte);

Var i, j: byte; { a - массив NxM, n<=30, m<=30 }

f: text; { name_f - имя файла }

begin assign(f, name_f); rewrite(f);

For i:= 1 to n do begin writeln(f);

For j:= 1 to m do write(f, a[i,j]:6:2) end;

close(f)

end;

{----------------------------------------------------------------}

Begin N:= 10; { создание симметричной матрицы }

for i:= 1 to N do for j:= i to N do

x[i, j]:= 0.5 + random(50); { заполнение верхней треугольной матрицы }

for i:= 1 to N do for j:= i to N do

x[j,i]:= x[i,j]; { заполнение нижней, симметричной части матрицы }

Wr_M(x, 'file_1.out', N, N); { вызов процедуры записи массива в файл }

end.

Для правильного считывания данных, записанных в файл бесформатным выводом необходима запись пробела для разделения чисел.

1.12.2 Рекурсивные функции и процедуры

Если одна процедура (Pr_2) вызывает в своем разделе выполнения другую (Pr_1), то вызываемая процедура должна быть описана во внешней программе перед описанием вызывающей процедуры, либо внутри вызывающей процедуры. Возможны и циклические случаи: если процедура вызывает сама себя - прямая рекурсия, если обе процедуры вызывают в своих разделах выполнения друг друга - косвенная рекурсия.

Если процедура вызывает сама себя (прямая рекурсия), то она описывается как обычно. Рекурсия традиционно применяется для итерационного расчета значения функции с использованием результатов предыдущего шага. Например, для расчета выражений вида: X! ( X факториал ), XN ( X в степени N ), вычисляемых по формулам: XN= XN-1 * k, где k - постоянная или переменная величина. В общем случае рекурсия применяется при расчете функции от функции: FN(x) = FN-1(x). При этом процесс происходит в два этапа: обратное движение с запоминанием цепочки расчета в оперативной памяти и прямое движение - расчет с использованием полученной цепочки. Рекурсивные процедуры требуют больше памяти для запоминания промежуточных результатов, чем обычные циклические операторы, поэтому рекурсии используются реже. В случае рекурсивных процедур следует обязательно предусмотреть условие окончания вызова процедуры.

Приведем пример традиционного использования рекурсии. Пусть требуется рассчитать число осколков, полученных в результате деления тела за "N" миллисекунд, если каждый осколок делится на два за одну миллисекунду. Тогда при N=0 число осколков = 1, при N>0 число осколков = 2N = 2*2(N-1).

Функция, возвращающая число осколков, будет иметь вид:

Function K_O(N: word): Longint;

begin

if N=0 then K_O:=1 {условие окончания рекурсии}

else K_O:=2*K_O(N-1) {рекурсивный вызов}

end;

Пример функции, возвращающей число осколков, без использования рекурсии:

Function K_O(N: word): Longint;

var N_1: Longint; i: word;

begin

N_1:=1; for i:=1 to N do N_1:= 2*N_1; K_0:= N_1

end;

Если к каждому осколку добавляется два осколка, то число осколков = (1+2)N= 3*3(N-1).

Во внешней программе число осколков (переменная "NN") расчитывается вызовом функции:

NN:= K_O(t);

где t - значение фактического параметра времени.

1.13 Разработка модулей

Известно, что откомпилированная программа размещается в отдельном сегменте памяти, т. е. не может превышать 64 Кбайта. Для создания больших программ в Турбо-Паскале предусмотрено подключение к основной программе откомпилированных модулей. Модуль включает в себя, как правило, большое число процедур, выполняющих однотипные операции, например, работа с графикой, операции с комплексными числами, матричные операции и т. д. Модуль определяется как программа, начинающаяся со служебного слова "Unit" и включающая в себя интерфейсную, исполняемую и инициирующую части.

Интерфейсная часть модуля начинается со служебного слова "Interface" и состоит из раздела описания глобальных имен типов, меток, констант, переменных, а также заголовков процедур, доступных основной программе.

Исполняемая часть модуля начинается со служебного слова "Implementation" и содержит полное описание процедур (заголовок, разделы описания и выполнения), заголовки которых перечислены в интерфейсной части, а также локальных имен типов, меток, констант и переменных, используемых в инициирующей части.

Инициирующая часть модуля начинается со служебного слова "Begin" и содержит блок операторов, выполняемых при подключении модуля к основной программе. Инициирующая часть вместе со словом "Begin" может отсутствовать или быть пустой. Заканчивается модуль служебным словом "End. " с точкой.

Содержимое исполняемой и инициирующей частей не доступно основной программе, связь модуля с основной программой осуществляется через интерфейсную часть модуля.

...

Подобные документы

  • Основные сведения о системе программирования Турбо Паскаль. Структура программы на Паскале и ее компоненты. Особенности и элементы языка Турбо Паскаль. Порядок выполнения операций в арифметическом выражении, стандартные функции и оператор присваивания.

    лекция [55,7 K], добавлен 21.05.2009

  • Язык программирования Турбо Паскаль. Запись алгоритма на языке программирования и отладка программы. Правила записи арифметических выражений. Стандартное расширение имени файла, созданного системным редактором. Составной оператор и вложенные условия.

    курсовая работа [75,0 K], добавлен 21.03.2013

  • Особенности программирования на языке Паскаль в среде Турбо Паскаль. Линейные алгоритмы, процедуры и функции. Структура данных: массивы, строки, записи. Модульное программирование, прямая и косвенная рекурсия. Бинарный поиск, организация списков.

    отчет по практике [913,8 K], добавлен 21.07.2012

  • Изучение истории создания языка Турбо-Паскаль, важнейшего инструмента для обучения методам структурного программирования. Анализ меню управления всеми ресурсами интегрированной инструментальной оболочки, зарезервированных слов, символьных переменных.

    презентация [989,7 K], добавлен 06.12.2011

  • Освоение технологии структурного программирования и применения стандартных методов работы с одномерными массивами при разработке и создании программы на языке Турбо Паскаль. Разработка программы методом пошаговой детализации с помощью псевдокода.

    реферат [276,9 K], добавлен 27.02.2008

  • Развертывание системы на жестком диске, диалоговая система программирования Турбо Паскаль, запуск программы и выполнение задания. Функциональные клавиши и их назначение. Текстовый редактор, средства создания и редактирования текстов программ, курсор.

    реферат [18,6 K], добавлен 01.04.2010

  • Сравнительный анализ языков программирования высокого уровня Си и Паскаль. Реализация алгоритма обработки данных. Тестирование и отладка программы или пакета программ. Структура программы на языке Турбо Паскаль. Указатели и векторные типы данных.

    курсовая работа [233,5 K], добавлен 14.12.2012

  • Особенности использования графического режима в среде Турбо Паскаль. Типы драйверов. Инициализация графики. Построение изображения на экране. Графические примитивы и работа с текстом. Разработка и реализация программ в среде Турбо Паскаль "Графика".

    курсовая работа [1,2 M], добавлен 26.09.2014

  • Международный стандарт на язык программирования Паскаль. Приемы объектно-ориентированного программирования в Турбо Паскале. Символы языка, его алфавит. Этапы разработки программы. Понятие алгоритмов и алгоритмизации. Структура программ на Паскале.

    курсовая работа [29,8 K], добавлен 28.02.2010

  • Особенности способов описания языков программирования. Язык программирования как способ записи программ на ЭВМ в понятной для компьютера форме. Характеристика языка Паскаль, анализ стандартных его функций. Анализ примеров записи арифметических выражений.

    курсовая работа [292,0 K], добавлен 18.03.2013

  • Расчет на устойчивость в системе программирования Турбо Паскаль. Определение критического напряжения стержня по формуле Ясинского, предельной гибкости в зависимости от материала. Программирование алгоритма расчета. Порядок ввода исходных данных.

    курсовая работа [1,0 M], добавлен 27.04.2013

  • Понятие алгоритма. Цикл программы. Структурная схема алгоритма. Элементы языка Тurbo Рascal. Алфавит. Идентификаторы. Комментарии. Лексика языка С++. ESC-последовательности. Операции. Ключевые слова. Комментарии.

    контрольная работа [43,0 K], добавлен 24.04.2006

  • Логические конструкции в системе программирования Паскаль. Команды языка программирования, использование функций, процедур. Постановка и решение задач механики в среде системы Паскаль. Задачи статики, кинематики, динамики решаемые с помощью языка Паскаль.

    курсовая работа [290,9 K], добавлен 05.12.2008

  • Изучение символьных и строковых типов данных, алгоритма задачи на языке программирования Паскаль. Описания получения и установки отдельного символа строки, изменения регистра символов. Анализ создания и просмотра файла, поиска и сортировки информации.

    курсовая работа [440,7 K], добавлен 13.06.2011

  • Общая характеристика языков программирования. Описание языка Паскаль: основные субъекты языка; структура Паскаль-программы; типизация и объявление данных. Операторы присваивания и выражения. Структурные операторы, организация ветвлений и циклов.

    дипломная работа [276,6 K], добавлен 26.01.2011

  • Разработка программы, создающей и управляющей базой данных, ее реализация на языке Turbo Pascal. Организация алгоритма программы. Вывод информации и возможность добавления информации в базу данных. Поиск информации в базе данных по заданному значению.

    курсовая работа [26,7 K], добавлен 19.06.2010

  • Разновидности и задачи подпрограмм в языке Турбо Паскаль, их локальные и глобальные параметры. Использование процедуры для выполнения законченной последовательности действий. Формат объявления функции, особенности рекурсивного оформления подпрограммы.

    реферат [20,0 K], добавлен 08.02.2012

  • Система программирования Турбо Паскаль. Главные особенности языка С++. Составной и условный оператор в Паскале, алгоритм работы. Метка в Турбо Паскале. Счетный оператор цикла FOR. Описание логической структуры. Свойства функции PieSlice и initgraph.

    курсовая работа [20,8 K], добавлен 23.12.2010

  • "Пятнашки" на первый взгляд простая игра, но для ее реализации необходимо обратится ко всем разделам программирования в среде Турбо Паскаль. Назначение и область применения. Описание алгоритма программы. Программное и аппаратное обеспечение программы.

    курсовая работа [308,0 K], добавлен 04.07.2008

  • Общая характеристика языка программирования Турбо Паскаль: операторы, циклы, файлы. Процедуры и функции модуля Crt. Структурная и функциональная схема программы учета учащихся, таблица идентификаторов. Список и описание использованных подпрограмм.

    курсовая работа [702,9 K], добавлен 29.01.2011

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.