Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
методические_указания_Паскаль.doc
Скачиваний:
56
Добавлен:
15.02.2015
Размер:
1.35 Mб
Скачать

Программирование с использованием подпрограмм

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

Краткие теоретические сведения

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

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

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

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

Формат описания процедуры:

Procedure <Имя процедуры> (<Имя форм. параметра 1>:<Тип>; < Имя форм. параметра 2>:<Тип>);

<Раздел описаний>

Begin <Тело процедуры>

End;

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

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

Формат описания функции: Function <Имя функции> (<Имя форм. параметра 1>:<Тип>; < Имя форм. параметра 2>:<Тип>) : <Тип результата>;

<Раздел описаний>

Begin <Тело функции>

End;

В теле функции обязательно должна быть хотя бы команда присвоения такого вида: <Имя функции>:=<Выражение>;

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

Вызов процедуры представляет в программе самостоятельную инструкцию: <Имя процедуры>(<Фактический параметр 1>, < Фактический параметр 2>);

Типы фактических параметров должны быть такими же, что и у соответствующих им формальных.

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

Приведем простейший пример использования подпрограммы.

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

Program Fn; Var A,B,C :Real; Function Max(A,B:Real):Real;{Описываем функцию Max с формальными} Begin {параметрами A и B, которая принимает }

If A>B Then Max:=A {значение максимального из них } Else Max:=B {Здесь A и B - локальные переменные }

End; Begin

Writeln('Введите три числа'); Readln(A,B,C); Writeln('Максимальным из всех является ', Max(Max(A,B),C))

End.

Существует два способа передачи фактических параметров в подпрограмму: по значению и по ссылке. В первом случае значение переменной-фактического параметра при вызове подпрограммы присваивается локальной переменной, являющейся формальным параметром подпрограммы. Что бы потом ни происходило с локальной переменной, это никак не отразится на соответствующей глобальной. Если требуется произвести в подпрограмме действия над самими переменными, указанными в качестве фактических параметров, то используется второй способ. Происходит следующее: при обращении к подпрограмме не происходит формирования локальной переменной-формального параметра. При этом на время выполнения подпрограммы имя этой локальной переменной будет указывать на ту же область памяти, что и имя соответствующей глобальной переменной. Если в этом случае изменить локальную переменную, изменятся данные и в глобальной.

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

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

Program Pr; Var S1,S2,S3 :Integer;

Procedure Swap(Var A,B: Integer);{Процедура Swap с параметрами-переменными} Var C : Integer; {C - независимая локальная переменная} Begin C:=A; A:=B; B:=C {Меняем местами содержимое A и B} End; Begin

Writeln('Введите три числа'); Readln(S1,S2,S3); If S1>S2 Then Swap(S1,S2); If S2>S3 Then Swap(S2,S3); If S1>S2 Then Swap(S1,S2); Writeln('Числа в порядке неубывания:V',S1,S2,S3)

End.

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

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

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

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

Основные действия, реализуемые при работе с файлами.

1. Описать тип файловой переменной. Например, переменная f в зависимости от типа файла может быть описана так:

var f : file of <тип>; {компонентный файл}

или

var f : text; {текстовый файл}

или

var 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).

Пример программы, демонстрирующей возможные действия с файлом:

Program Files;

Var

a:array[1..10] of real;

f: text;

i: integer;

Begin

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

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

WriteLn(f,'Вектор a');

for i:=1 to 10 do

begin

a[i]:=random*10;

Write(f,a[i]:6:2,' '); { Запись массива a в файл }

end;

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

Reset(f); { Открытие файл для чтения}

Readln(f);

for i:=1 to 10 do

Read(f,a[i]); { Cчитывание массива a из файла }

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

End.

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

  1. Процедура Append(var f : Text); Открывает существующий текстовый файл f для дополнения.

  2. Процедура Assign(var f; name : String); Связывает внешний файл с именем name и переменную файлового типа f. Все дальнейшие операции с переменной f будут выполняться с указанным внешним файлом.

  3. Процедура Close(var f); Закрывает открытый файл, связанный с переменной f.

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

  5. Функция FilePos(var f); типа Longint; Показывает текущую позицию в файле, указываемом переменной f. Если эта позиция в конце файла, то функция возвращает значение, равное длине файла, а если в начале файла, значение 0.

  6. Функция FileSize(var f); типа Longint; Показывает текущий размер файла f в байтах. Если файл пуст, то 0.

  7. Процедура Reset(var f [ : file; RecSize : Word ] ); Открытие существующего файла. Имя внешнего файла, связанного с f, должно быть ранее определено. Необязательный параметр RecSize: размер записи нетипизированного файла.

  8. Процедура Rewrite(var f : file [;RecSize : Word ] ); Создает и открывает новый файл. Если такой файл уже есть, то он удаляется и создается новый с тем же именем.

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

  10. Процедура Truncate(var f); Усекает размер файла f до текущей позиции в файле.

Задание на работу

Разработать программу по заданию, соответствующему варианту.

Таблица 14 – Варианты заданий

Номер варианта

Задание

0

Считать случайную матрицу A=[5X5] из файла, созданного с помощью процедуры random, матрицу передать в процедуру, в ней с помощью этой матрицы создать 2 новых матрицы Symm= A+At и AntiSymm= A-At. Эти 2 новые матрицы вернуть в главную программу и распечатать по строкам.

1

Считать случайную матрицу A=[5X5] из файла, созданного с помощью процедуры random, матрицу передать в процедуру, в ней для каждой строки матрицы найти среднее значение Sij Aij /N и средне-квадратичное отклонение Сij (Aij –Si)2 /N. Эти 2 новых вектора вернуть в главную программу и распечатать.

2

Считать случайный массив A=[10] из файла, созданного с помощью процедуры random и сдвига на -0.5, массив передать в функцию, в нем подсчитать число чередований знака в массиве (т.е переходов с плюса на минус и с минуса на плюс) и вернуть в главную программу и распечатать.

3

Считать случайный массив A=[10] из файла, созданного с помощью процедуры random и сдвига на -0.5, массив передать в процедуру, в ней упорядочить массив по возрастанию ( с помощью двойного цикла) и вернуть в главную программу и распечатать.

4

Считать случайную матрицу A=[5X5] из файла, созданного с помощью процедуры random, матрицу передать в процедуру, в ней для каждой строки матрицы найти разность максимального и минимального элемента строки и вернуть этот вектор в главную программу и распечатать.

5

Считать случайный массив A=[10] из файла, созданного с помощью процедуры random и сдвига на -0.5, массив передать в процедуру, в нем выделить новый массив B, в котором останутся элементы А, меньшие по модулю 0.3 и вернуть B в главную программу и распечатать.

6

Считать случайную матрицу A=[5X5] из файла, созданного с помощью процедуры random, матрицу передать в процедуру, в ней для каждой строки матрицы найти среднее значение Sij Aij /N и вычислить матрицу B=exp(Aij- Si ). Эту матрицу B вернуть в главную программу и распечатать по строкам.

7

Считать случайную матрицу A=[5X5] из файла, созданного с помощью процедуры random, матрицу передать в процедуру, в ней для каждой строки матрицы найти среднее значение Sij Aij /N и вычислить матрицу Bij=(Si - Sj). Эту матрицу B вернуть в главную программу и распечатать по строкам.

8

Считать случайный массив A=[10] из файла, созданного с помощью процедуры random и сдвига на -0.5, массив передать в процедуру, в ней создать новый массив В, совпадающий с А, но в котором 4 минимальных элемента старого массива стоят на первых местах, этот массив вернуть в главную программу и распечатать оба массива .

9

Считать случайный массив A=[10] из файла, созданного с помощью процедуры random, массив передать в функцию, в нем подсчитать целочисленный массив В, равный числу элементов А, лежащих между 0 и 0.1, 0.1 и 0.2, 0.2 и 0.3 и т.д число чередований знака в массиве (т.е переходов с плюса на минус и с минуса на плюс) и вернуть В в главную программу и распечатать.

Лабораторная работа № 8