ТОП 10:

Процедуры и функции пользователя



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

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

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

Заголовок процедуры имеет следующий вид:

Procedure идентификатор [(параметры)];

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

Список параметров может состоять из нескольких групп параметров, разделенных точкой с запятой (;):

(группа параметров [; группа параметров [; …] ] ).

Группа параметров, которая содержит список параметров одного типа, может быть трех следующих видов:

§ идентификатор [, идентификатор [,…] ]: type (список параметров-значений - только передают значения в процедуру)

§ var идентификатор [, идентификатор [,…] ]: type (список параметров-переменных – возвращают значения в вызывающую программу из процедуры)

§ var идентификатор [, идентификатор [,…] ] (список нетипизированных параметров-переменных)

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

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

Procedure WrStr(X, Y: integer; S: string); {заголовок}

var {описание локальных переменных}

SaveX, SaveY: Integer;

begin

SaveX := WhereX; {запоминаем позицию курсора на экране по Х}

SaveY := WhereY; {то же по Y}

GotoXY(X,Y); {перемещаем курсор в заданную позицию X,Y}

Write(S); {выводим с заданной позиции строку текста}

GotoXY(SaveX, SaveY); {перемещаем курсор в исходную позицию}

end;

Обращение к ней из головной программы или другой процедуры может выглядеть следующим образом: WrStr(40, 2, ’Расчет …’):

Процедура может использовать глобальные переменные и переменные вызывающей программы, параметры этой процедуры и свои локальные переменные.

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

Функция, в отличие от процедуры, имеет имя, которое принимает определенное значение после ее выполнения. Описание функции:

{функция, которая преобразует все символы строки в прописные}

Function UpCaseStr(S: string): string; {заголовок}

var i : integer; {раздел описаний локальных переменных}

begin {начало тела функции}

for i := 1 to Length(S) do

if (S[i] >= 'a') and (S[i] <= 'z') then Dec(S[i], 32);

UpCaseStr := S;

end; {конец описания функции}

Вызов этой функции из головной программы или другой процедуры может выглядеть следующим образом: Write(UpCaseStr(’Расчет …’)).

Использование подобных функций пользователя ничем не отличается от использования стандартных функций вроде Sin(x), Exp(a) и проч.

Ниже приведён пример построения программы с разбиением её на отдельные процедуры:

 

Program Prg_proc;

Uses Crt, Printer;

Var

xn, xk, h : real;

i, j, m, n : word;

x, y : array [1..50] of real;

mnu : array [1..6] of string[15];

vv : char;

 

Procedure my_mnu;

begin

Window(1, 1, 80, 1); TextColor(0); gotoXY(1,1);

for i:=1 to 5 do

if i=m then

begin

TextBackground(2);Write(' ',mnu[i],' ');

end

else

begin

TextBackground(7); Write(' ',mnu[i],' ');

end;

Window(1, 2, 80, 25);

gotoXY(1,1); TextColor(15);TextBackground(0);

end;

 

Procedure input_kl;

begin

ClrScr;

Write('x начальное = '); Readln(xn);

Write('x конечное = '); Readln(xk);

Write('количество точек графика (n<50) = '); Readln(n);

m:=2; my_mnu

end;

 

Procedure calc_dat;

begin

x[1]:=xn;

h:=(xk-xn)/(n-1);

for i:=1 to n do

begin

y[i]:=sin(x[i]); x[i+1]:=x[i]+h;

end;

ClrScr; write('Расчет выполнен!')

end;

 

Procedure out_dat;

begin

ClrScr;

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

Writeln(' X Y ');

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

for i:=1 to n do writeln(x[i]:15:5,Y[i]:15:5);

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

end;

 

Procedure out_gr;

begin

Write('здесь нужно описать вывод графика на экран')

end;

 

begin {головная программа}

TextBackground(0); ClrScr;

mnu[1]:='Исх.данные';

mnu[2]:='Расчет' ;

mnu[3]:='Таблица';

mnu[4]:='График' ;

mnu[5]:='Выход' ;

m:=1;

my_mnu;

repeat

vv:=Readkey;

if ord(vv)=0 then vv:=Readkey;

case ORD(VV) of

13:begin

case m of

1:input_kl;

2:calc_dat;

3:out_dat ;

4:out_gr ;

end;

end;

77:begin if m<5 then m:=m+1 else m:=1; my_mnu end;

75:begin if m>1 then m:=m-1 else m:=5; my_mnu end;

end;

until (vv=chr(13)) and (m=5);

end.

Задание

Ввести текст программы Prg_proc с клавиатуры в системе Turbo Pascal. Сохранить файл в свою папку. Выполнить отладку программы. Дополнить программу процедурой вывода расчетной таблицы на принтер.

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

1. y = exp( - a×x2) 6. y = ax;
2. y = x /(sin(5x)+1,5) 7. y = | cos(x)|;
3. y = a × x2 + b × x + c 8. y = x/(1-x2);
4. y = ± , где -r £ x £ r 9. y = ± x ;
5. E = 1010 / 10. y = 0,1×x×sin(x/0,5)

Тема 12

Записи

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

Запись – это структурированный тип данных, состоящий из фиксированного числа компонентов разного типа. Определение типа начинается идентификатором Record и заканчивается ключевым словом end. Между ними заключён список компонентов, называемых полями, с указанием идентификаторов полей и типа каждого поля.

Формат описания типа запись:

Type

<имя типа> = Record

<идентификатор поля>:<тип компонента>;

.......

<идентификатор поля>:<тип компонента>;

end;

Var

<идентификатор, ...> : <имя типа>;

Пример 1.

Type

avto = record

Nomer:string[6]; { Регистрационный номер }

Marka:string[15]; { марка автомобиля }

God:integer; { год выпуска }

Color: string[20]; { цвет }

Fam:string[20]; { фамилия владельца }

Adress:string[40]; { адрес владельца }

end;

Var

m,v:avto;

В данном примере запись avto содержит 6 компонентов: номер, марка машины, год выпуска, цвет, фамилия владельца, его адрес. Доступ к полям записи осуществляется через переменные m и v типа record.

Имя поля должно быть уникальным в пределах записи. Объём памяти, необходимый для хранения записи, складывается из длин полей.

Значения полей записи могут быть использованы в выражениях. Обращение к значению поля осуществляется с помощью составного имени, включающего идентификатор переменной и идентификатор поля, разделённые точкой. Например, чтобы получить доступ к полям записи m типа avto, надо записать:

m.nomer, m.marka, m.god, m.color, m.fam, m.adress.

Для присваивания полям записей значений используются оператор присваивания.

m.nomer:=’ав345х’;

m.marka:=’ВАЗ 2110’;

m.god:=1995;

Составные имена можно использовать, в частности, в операторах ввода-вывода

Write(’Введите фамилию владельца автомобиля ’,m.nomer, ’ ’);

Readln(m.fam);

Допускается применение оператора присваивания к записям в целом, если они имеют один и тот же тип, например, m:=v. После этого значения полей записи m станут равны значениям соответствующих полей записи v.

В ряде задач удобно пользоваться массивами из записей. Их можно описать, например, следующим образом:

Type

Person = record

Fam:string[20]; { фамилия сотрудника }

Pol:char; { Пол сотрудника }

Age:16..60; { возраст сотрудника}

Dolgnost: string[20]; { должность }

end;

Var

otdel:array [1..50] of Person;

Обращение к полям записей имеет несколько громоздкий вид, что особенно заметно при использовании идентификаторов длиной более 5 символов. Для решения этой проблемы применяется оператор with, который имеет следующий формат:

With <переменная типа record> do <оператор>;

Один раз указав имя переменной типа record в операторе with, далее в пределах блока <оператор> можно работать с именами полей, как с обычными переменными, то есть без указания перед идентификатором поля имени переменной, определяющей запись:

With Otdel[25] do

begin

fam:=’Васильев’;

Pol:=’М’;

Age:=45;

Dolgnost:=’Директор’;

end;

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

Записи используются обычно для организации файлов с данными на магнитных дисках.

Задания

Организовать ввод, хранение в массиве, вывод на экран следующих данных:

1. Информация о движении поездов, включающая номер поезда, пункт отправления, пункт назначения, дата и время отправления, время в пути.

2. Информация о продаже билетов в кинотеатре, включающая дату, время сеанса, ряд, место, признак проданного билета.

3. Информация о знакоместах экрана монитора, работающего в текстовом режиме: строка, позиция в строке, символ, цвет символа, цвет фона.

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

5. Информация о владельцах животных: фамилия владельца, вид животного, порода, окрас, пол, возраст животного.

6. Экзаменационная ведомость: предмет, номер группы, дата экзамена, 10 строчек с фамилиями студентов, номером их зачётной книжки, оценкой.

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

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

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

10. Информация о квартиросъёмщиках в многоквартирном доме: номер квартиры, фамилия квартиросъёмщика, подъезд, этаж, общая площадь, жилая площадь, количество проживающих.

11. Информация о выдаче книг в библиотеке: шифр книги, тематика, автор, название, издательство, год издания, количество страниц.

 

Тема 13

Работа с файлами

Файлом называется последовательность данных, размещаемая на внешнем запоминающем устройстве и рассматриваемая в процессе чтения-записи как единое целое.

Порядок работы с файлами:

1. Описать тип файловой переменной, например, f :

var var var
f : file of type; f : text; f : file;

Тип file описывает линейную последовательность компонент, указанного типа. Тип файла Text означает файл, состоящий из строк символов.

2. Осуществить связь файловой переменной с именем файла - команда Assign(f). Одновременно в программе может быть открыто несколько десятков файлов, каждый из которых должен иметь свою файловую переменную.

3. Открыть файл командой Rewrite(f) для записи во вновь создаваемый файл или Reset(f)для чтения/записи уже имеющегося файла. Если открывается существующий текстовый файл, то используем команду
Append(f).

4. Осуществить чтение/запись в файл - команды Read/Writeсоответственно (для построчной работы с текстовыми файлами можно использовать ReadLn/WriteLn). Например, команда записи выглядит следующим образом: Write(f, а), где f - файловая переменная; а - переменная любого типа (byte, real, string и т. д., соответствующая типу файла). При обращении к командам Read/Writeпозиция чтения/записи в файле автоматически увеличивается на единицу.

5. Закрыть файла - команда Close(f).

Пример:

Var

f: text;

Begin

Assign(f, 'TEST.TXT'); { связываем файловую переменную f }
{ c именем файла 'TEST.TXT' }

Rewrite(f); { Создаем новый файл }

WriteLn(f,'Исходный текст'); { Записываем строку в файл }

Close(f); { Закрываем файл }

Append(f); { Открыть файл для добавления}

{ в его конец строки }

WriteLn(f,'Добавляемый текст'); { Добавляем строку }

Close(f); { Закрываем файл}

End.

Ниже приведено описание процедур и функций, работающих с файлами:

Procedure Append(var f : Text);

Открывает существующий текстовый файл fдля дополнения.

Procedure Assign(var f; name : String);

Связывает внешний файл с именем name и переменную файлового типа f. Все дальнейшие операции с переменной f будут выполняться с указанным внешним файлом.

Procedure Close(var f);

Закрывает открытый файл, связанный с переменной f.

Function Eof(var f) : Boolean;

Показывает значение Истина (True) при наличии признака конца файла для типизированных или нетипизированных файлов, указываемых файловой переменной f.

Function FilePos(var f) : Longint;

Показывает текущую позицию в файле, указываемом переменной f. Если эта позиция в конце файла, то функция возвращает значение, равное длине файла, а если в начале файла, значение 0.

Function FileSize(var f) : Longint;

Показывает текущий размер файла f в байтах. Если файл пуст, то 0.

Procedure Reset(var f [ : file; RecSize : Word ] );

Открытие существующего файла. Имя внешнего файла, связанного с f, должно быть ранее определено. Необязательный параметр RecSize: размер записи нетипизированного файла.

Procedure Rewrite(var f : file [;RecSize : Word ] );

Создает и открывает новый файл. Если такой файл уже есть, то он удаляется и создается новый с тем же именем.

Procedure Seek(var f; n : Longint);

Перемещает текущую позицию файла к элементу с номером n (не может быть использована для текстовых файлов, первая позиция равна 0).

Procedure Truncate(var f);

Усекает размер файла f до текущей позиции в файле.

Ниже приведен пример программы, которая открывает сразу два файла (один для чтения, а второй создает вновь для записи). Командой Readln(f1,s);из первого файла считывается строка s. В цикле For организуется доступ к ее отдельным символам и производится замена буквы k на K. Затем преобразованная строка сохраняется во втором файле. Считывание строк проводится в цикле repeat-until и завершается при нахождении конца первого файлаEof(f1).

Var

f1,f2:text;

s:string;

i:byte;

Begin

Assign(f1, 'text.txt');

Assign(f2, 'text_new.txt');

Reset(f1);

Rewrite(f2);

Repeat

Readln(f1, s);

for i:=1 to Length(s) do

if s[i]='k' then s[i]:='K';

WriteLn(f2, s);

until Eof(f1);

Close(f1);

Close(f2);

End.

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

Var

f1,f2:file of char;

ch:char;

Begin

Assign(f1, 'text.txt');

Assign(f2, 'text_new.txt');

Reset(f1);

Rewrite(f2);

Repeat

Read(f1, ch);

if ch='k' then ch:='K';

Write(f2, ch);

Until Eof(f1);

Close(f1);

Close(f2);

End.

Задания

Вариант 1

а) Создать текстовый файл, в котором имеется 100 строк и в каждой строке содержится ее номер.

б) Создать программу, которая все числа в файле, кратные 10, заменяет символом «!».

Вариант 2

а) Создать файл, состоящий из 10 записей. Каждая запись должна иметь следующую структуру: фамилия, номер телефона, адрес. Заполните файл данными о студентах Вашей группы.

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

Вариант 3

а) Создать файл, состоящий из 15 записей. Каждая запись должна иметь следующую структуру: фамилию, дату рождения (год, месяц, день). Заполните файл данными о студентах Вашей группы.

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

Вариант 4

а) Создать файл, состоящий из 15 записей, в которых хранится информация о имеющихся в лаборатории химических реактивах. Каждая запись должна иметь следующую структуру: название вещества, масса или объем, степень очистки, номер шкафа, номер полки. Заполните файл данными.

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

Вариант 5

Создать программу, которая обрабатывает текстовый файл таким образом, что начиная с третьей строки, все буквы «Р» заменяет на буквы «Л».

Вариант 6

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

Вариант 7

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

Вариант 8

а) Создать программу, которая записывает в файл типа byte 1000 случайных чисел от 0 до 255 и программу, которая записывает такие же числа в текстовый файл.

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

Вариант 9

Создать программу, которая выводит на экран сообщение «Привет!», причем информацию о цвете букв, фона, расположении надписи на экране берет из файла privet.cfg, созданного ранее.

Вариант 10

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


 

Тема 14







Последнее изменение этой страницы: 2016-04-18; Нарушение авторского права страницы

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.226.243.36 (0.027 с.)