КулЛиб - Классная библиотека! Скачать книги бесплатно 

Моделирование инженерных задач на языке программирования Free Pascal в среде Lazarus: учебное пособие [Никита Николаевич Дмитриев] (pdf) читать онлайн

Книга в формате pdf! Изображения и текст могут не отображаться!


 [Настройки текста]  [Cбросить фильтры]
Н.Н. ДМИТРИЕВ, В.Ю. САХАРОВ

МОДЕЛИРОВАНИЕ
ИНЖЕНЕРНЫХ ЗАДАЧ
НА ЯЗЫКЕ
ПРОГРАММИРОВАНИЯ
FREE PASCAL
В СРЕДЕ LAZARUS

Министерство образования и науки Российской Федерации
Балтийский государственный технический университет «Военмех»

Н.Н. ДМИТРИЕВ, В.Ю. САХАРОВ

МОДЕЛИРОВАНИЕ ИНЖЕНЕРНЫХ
ЗАДАЧ НА ЯЗЫКЕ
ПРОГРАММИРОВАНИЯ FREE PASCAL
В СРЕДЕ LAZARUS
Учебное пособие

Санкт-Петербург
2012

УДК 004.43(075)
Д53
Д53

Дмитриев, Н.Н.
Моделирование инженерных задач на языке
программирования Free Pascal в среде Lazarus:
учебное пособие / Н.Н. Дмитриев, В.Ю. Сахаров;
Балт. гос. техн. ун-т. – СПб., 2012. – 56 с.
ISBN 978-5-85546-721-5
Излагаются основы языка программирования Free
Pascal. Рассматриваются алгоритмы решения некоторых математических задач. Разбирается алгоритм численного решения задачи Коши методом Рунге–Кутта
четвертого порядка на примере задач механики.
Предназначено для студентов 2-4-го курсов всех
специальностей.

УДК 004.43(075)

Р е ц е н з е н т ы: канд. техн. наук, проф. БГТУ Н.Н. Смирнова;
канд. физ.-мат. наук, доц. БГТУ А.Л. Илихменев

Утверждено
редакционно-издательским
советом университета

ISBN 978-5-85546-721-5

© Авторы, 2012
© БГТУ, 2012

ПРЕДИСЛОВИЕ
Данное учебное пособие предназначено для студентов, которым необходимы основы программирования на языке высокого
уровня Free Pascal. В частности оно будет весьма полезным для
студентов, которые изучают механику, и при решении задач нужно
численно найти решение задачи Коши для системы дифференциальных уравнений. Такого вида задачи возникают в курсах теоретической механики, теории колебаний, основ теории трения
и др.
Подчеркнем, что Free Pascal и среда разработки Lazarus – свободно распространяемый программный продукт. Установка Free
Pascal или среды Lazarus на домашнем или рабочем компьютере
дает возможность работать на легальном программном обеспечении. Кроме того, Lazarus устанавливается на ПК с ОС Windows,
Linux или Mac OC X (http://lazarus.freepascal.org).
Для более глубокого изучения Lazarus и Free Pascal можно
рекомендовать книгу К.Т. Мансурова «Основы программирования
в среде Lazarus» (текст этой книги можно найти на сайте
http://www. freepascal.ru).

3

1. ВВЕДЕНИЕ В ПРОГРАММИРОВАНИЕ
1.1. Структурное программирование
С момента зарождения программирования было создано множество языков общения человека с ЭВМ. Сейчас, по видимости,
наибольшее распространение имеют языки программирования C++,
Delphi, Visual Basic (Visual Basic for Application), Free Pascal и некоторые другие. При этом в каждом из этих языков есть поддержка
всех классических управляющих конструкций.
К 70-м годам XX в. стало ясно, что программные проекты стали
слишком сложными для успешного проектирования, кодирования и
отладки в приемлемые сроки. Размер программ достиг величин, при
которых программисты не могли с уверенностью сказать, что созданный программный продукт всегда выполняет то, что требуется и
что он не выполняет ничего такого, что не требуется. Назрела проблема изменения подходов к созданию больших программных продуктов.
В 1969 г. Э. Дейкстра на международной конференции по программированию впервые использовал термин «структурное программирование» и предложил принципиально новый способ создания программ. Программа рассматривалась им как совокупность
иерархических абстрактных уровней, которые позволяют четко
структурировать программу и лучше ее понимать, доказывать корректность ее работы и тем самым повышать надежность функционирования программы и сократить сроки ее разработки.
Правила структурной методологии разрабатывались такими учеными как Вирт, Дейкстра, Дал, Хоар, Иордан и др.
В этой связи следует отметить знаменитые книги Вирта [8, 9] и
сборник [4].

4

1.1.1. Цели структурного программирования
Обеспечить дисциплину программирования в процессе создания программных комплексов. Дейкстра дал следующее определение: «Структурное программирование – это дисциплина, которую программист навязывает сам себе».
Улучшить читабельность программы. Для этого следует избегать использования языковых конструкций с неочевидной семантикой; стремиться к локализации действия управляющих конструкций
и применения структур данных; разрабатывать программу так, чтобы ее можно было читать от начала до конца без управляющих переходов на другую страницу.
Повышать эффективность программы. Данное положение
достигается при структурировании программы, разбиении ее на модули так, чтобы можно было легко находить и корректировать
ошибки, а также чтобы текст любого модуля с целью увеличения
эффективности можно было переделать независимо от других.
Повышать надежность программы. Надежность обеспечивается хорошим структурированием программы при разбивке ее на
модули и выполнением правил написания читабельных программ,
что ведет к возможности сквозного тестирования и не создает проблем для организации процесса отладки.
Уменьшать время и стоимость программной разработки. Этот
пункт выполняется, когда повышается производительность труда
программиста, чему способствуют правила структурного программирования.
1.1.2. Основные принципы структурной методологии
Принцип абстракции. Абстракция позволяет придумать решение задачи без сиюминутного учета множества деталей. Поэтому
проблема может рассматриваться по уровням: верхний уровень показывает большую абстракцию, упрощает взгляд на проект, нижний
– показывает мелкие детали реализации задачи.
Принцип формальности. Формальность позволяет перейти от
импровизации к строгому инженерному подходу при написании
программ. Более того, этот принцип дает основания для доказатель-

5

ства правильности программ, так как позволяет изучать алгоритмы
как математические объекты.
Принцип «разделяй и властвуй». Этот принцип означает возможность разделения программы на отдельные модули, которые
просты по управлению и допускают независимую отладку и тестирование.
Принцип иерархического упорядочения. Данный принцип тесно
связан с принципом «разделяй и властвуй» и выдвигает требования
иерархического структурирования взаимосвязей между модулями
программного комплекса, что облегчает достижение структурного
программирования.
1.2. Модульное программирование
Модульное программирование – это организация программы
как совокупности небольших независимых блоков, называемых модулями, структура и поведение которых подчиняются определенным правилам. Первое основное свойство программного модуля
сформулировал Парнас (Parnas): «Для написания одного модуля
должно быть достаточно минимальных знаний о тексте другого». Но
только в 1975 г. Н. Вирт впервые предложил специализированную
синтаксическую конструкцию модуля и включил в новый язык программирования Modula. Сейчас аналогичные конструкции имеются
во многих языках.
Некоторые из этапов и приемов программирования и разработки алгоритмов [4]:
1. Никаких трюков и заумного программирования. Не нужно
применять сложные методы там, где можно использовать простые.
2. Как можно меньше переходов. Программирование без
go to – это еще не структурное программирование. В некоторых ситуациях переход по go to является лаконичным, простым и ясным
средством. Но разумное применение конструкций if-then-else и fordo способствует большей ясности, чем использование оператора go
to.
3. Выбор с использованием конструкции if-then-else. Цель
данного положения – обеспечение простоты хода вычисления, без
каких то ни было переходов извне внутрь рассматриваемой структуры.
6

4. Простота циклов. Переходы по программе назад почти всегда можно представить как некоторую форму цикла. Существуют
формы цикла for-do, while-do, repeat-until.
Можно написать
k:=0; while k0 then begin
7

if i=1 then mult:=1 else mult:=fact2(i-1);
fact2:=mult*i
end
end{fact2};
function fact2_1(i:integer):int64; // вычисление факториала
//перемножением последовательности чисел
var mult:int64;
j:integer;
begin
if i=0 then fact2_1:=1;
if i>0 then begin
fact2_1:=1;
for j:=1 to i do
fact2_1:=fact2_1*j
end
end{fact2};
7. Содержательные обозначения. Может показаться, что
краткие имена ускоряют и упрощают написание программы. Но,
когда через некоторое время программу потребуется модифицировать, простота понимания, обеспечиваемая содержательными обозначениями, полностью окупит затраченные при программировании
усилия.
Очевидно, что к приведенным семи правилам можно добавить
некоторые другие. Но, если придерживаться перечисленных правил,
то можно писать программы, которые легко понимать и сопровождать.
1.3. Некоторые понятия об объектно-ориентированной
методологии программирования
Следующим этапом развития науки программирования стало
создание объектно-ориентированной методологии.
Объектно-ориентированная методология программирования
преследует те же цели, что и структурная, но решает их с другой
отправной точки. По определению Г. Буча [1], «объектно-ориентированное программирование – это методология программирования,
которая основана на представлении программы в виде совокупно8

сти объектов, каждый из которых является реализацией определенного класса (типа), а классы (типы) образуют иерархию на принципах наследуемости».
Один из принципов управления сложностью проекта – декомпозиция. Г. Буч выделяет две разновидности декомпозиции: алгоритмическую, которую поддерживают структурные методы, и объектно-ориентированную, отличие которой состоит в следующем:
«Разделение по алгоритмам концентрирует внимание на порядке
происходящих событий, а разделение по объектам придает особое
значение факторам, либо вызывающим действия, либо являющимся
объектами приложения этих действий». Другими словами, алгоритмическая декомпозиция учитывает в бóльшей степени структуру взаимосвязей между частями сложной проблемы, а объектно-ориентированная уделяет бóльшее внимание характеру взаимодействий.
На практике следует использовать обе разновидности. При создании крупных проектов сначала следует применить объектноориентированный подход для конструирования общей иерархии объектов, отражающих сущность программной задачи, а затем использовать алгоритмическую декомпозицию на модули для упрощения разработки, отладки и сопровождения программного комплекса.
Следует подчеркнуть [3], что в некоторых областях, таких как
интерактивная графика, объектно-ориентированное программирование весьма полезно. В других задачах, таких как классические
арифметические типы и вычисления, основанные на них, похоже
трудно найти применение чему-то большему, чем абстракция данных, а средства, необходимые для поддержки объектно-ориентированного программирования, выглядят бесполезными.
2. ОСНОВЫ ЯЗЫКА ПРОГРАММИРОВАНИЯ
FREE PASCAL
В настоящее время существуют среды разработки программ,
которые распространяются свободно (бесплатно). Для некоторых из
них требуется регистрация, другие после закачки с соответствующего сайта сразу могут быть установлены на компьютер. Отметим
интересующий нас источник: Free Pascal (www.freepascal.ru или
http://lazarus.freepascal.org).
9

Приведем некоторые начальные сведения о программировании
на языке Pascal, являющемся основой Free Pascal. Особенности среды разработки здесь затрагивать не будем. Но изучение нижеизложенного позволяет приступить к написанию своих собственных,
вначале несложных, приложений.
2.1. Словарь языка Pascal
В любом языке программирования имеются символы и слова,
которые компьютер понимает изначально. Эти значки и слова
нельзя употреблять как имена переменных. Имена переменных
часто называют идентификаторами. Идентификатор – это последовательность букв и цифр, начинающаяся с буквы.
З а м е ч а н и е. Пробелы в идентификаторах не допускаются!
Ограничители и специальные символы
+

:=

:

<

(

..

-

.





[

}

/

;



>=

]

^

Ключевые слова
Absolute
Begin
Destructor
Else
For
If
Interface
Nil
Or
Record
Shr
Type
Var
Xor

And
Case
Div
End
Forward
Implementation
Interrupt
Not
Packed
Repeat
String
Unit
Virtual

Array
Const
Do
External
Function
In
Label
Object
Procedure
Set
Then
Until
While

10

Asm
Constructor
Downto
File
Goto
Inline
Mod
Of
Program
Shl
To
Uses
with

2.2. Данные
Всякая программа предназначена для обработки данных различной природы (числа, тексты, последовательности двоичных разрядов или битов и т.д.). В зависимости от способа их хранения и
обработки, данные можно разбить на две группы: константы и переменные.
Константы – это данные, которые не изменяются в процессе
работы программы. Переменные – это данные, которые могут изменяться во время выполнения программы.
В Pascal константы могут быть трех видов: числовые, булевские
(логические) и символьные.
Описание констант:
Const a=5; d=’ABC’; L=True;
Каждая переменная должна быть объявлена до своего первого
применения. Тип переменной определяет множество допустимых
для нее значений. Приведем некоторые стандартные типы данных:
Тип данных
Integer
Int64
Byte
Word
Real 48
Double
Boolean
Char
String

Диапазон
-32768…32767
-263…+263-1 целое число со знаком
0…255
0…65535
±2.9E-39… ±1.7E+38
±5.0E-324… ±1.7E+308
False, True
Множество символов ASCII
Строка символов (до 255 символов)

Имеются и другие типы данных.
Пример описания переменных:
Var
A,B:real;
S:string;
S1,S2:string;
I,j,k:integer;
AA, BB: double;

11

2.3. Структура программы
Программы, написанные на языке программирования Pascal и в
основанных на нем средах разработки, имеют четкую структуру –
состоят из заголовка и блока. Заголовок – это ключевое слово Program и имя программы, после которых ставится точка с запятой.
Например:
Program P;
З а м е ч а н и е. Заголовок программы – неисполняемый оператор, то есть рассматривается компьютером как комментарий.
Блок программы состоит из шести разделов:
1) раздел меток (Label);
2) раздел констант (Const);
3) раздел типов (Type);
4) раздел переменных (Var);
5) раздел процедур и функций (Procedure, Function);
6) раздел действий.
З а м е ч а н и е. Раздел действий должен присутствовать всегда, остальные могут отсутствовать.
Первые четыре раздела начинаются с соответствующих ключевых слов (Label, Const, Type, Var).
Раздел меток (Label). Любой выполняемый оператор может
быть снабжен меткой – целочисленным числом от 0 до 9999 или
идентификатором. Каждая описанная метка должна появиться в
программе, причем ровно один раз. Метка отделяется от оператора
двоеточием.
Пример:
Label L1, 25;
……………
L1: log:=true;
25: a:=b;
……………
Раздел констант (Const). Если в программе используются
константы (не обязательно числа), то удобно их обозначить какимлибо именем и далее обращаться к этой постоянной величине по
имени. Отметим, что при построении выражения для определения
значения констант можно использовать только ранее описанные
константы, соединенные знаками операций и функциями (Abs, Chr,
12

Hi, Length, Odd, Ord, Round, Trunc и некоторые другие). Имеются
предопределенные константы
Константа
Maxint=32767
MaxLongInt=2147483647
False, True
Pi=3.1415926

Тип
Integer
LongInt
Boolean
Real

Раздел типов (Type). Если в программе вводится тип, отличный от стандартного, то этот тип описывается в разделе Type. Синтаксис этого действия состоит из ключевого слова Type, идентификаторов определяемых типов, значка равно «=» и описания вида
типа:
Type T=;
TT=;
Пример:
Type Index=1..20;
A=array[index] of real;
Раздел переменных (Var). Каждая переменная, встречающаяся
в программе, должна быть описана до ее использования и отнесена
к одному и только одному типу.
Пример:
Var r1, r2:real;
I,j,k:integer;
B:array[1..25] of real;
Область действия переменных определяется по правилу: переменные локальны в блоке, где описаны, а также во всех вложенных блоках, если в них они не описаны повторно.
Раздел действий. Эта часть программы начинается с ключевого слова Begin и заканчивается словом End, после которого ставится точка. Раздел действий – это выполняемая часть программы, состоящая из операторов.
2.4. Операторы
В языке программирования Pascal под операторами подразумеваются только действия. Операторы отделяются друг от друга точ13

кой с запятой. Точку с запятой можно не ставить перед словами
End и Until, поскольку такая запись будет означать наличие пустого оператора между этой точкой с запятой и указанным служебным
словом. Категорически нельзя ставить точку с запятой перед словом
Else, поскольку между Then и Else должен стоять ровно один оператор, а не два и более.
Оператор присваивания. Пусть V – переменная, A – выражение. Тогда операция присваивания записывается в виде
V:=A;
Выражение A может содержать константы, переменные, знаки
операций, функции, скобки. Любое выражение в скобках вычисляется раньше, чем операция, предшествующая скобкам.
З а м е ч а н и я 1. Присваивание допускается для всех типов, за
исключением типа файл.
2. Переменной типа real (double) можно присвоить выражение
типа integer, но переменной имеющей тип integer присвоить выражение типа real нельзя.
Составной оператор начинается ключевым словом Begin и заканчивается словом End. Между этими словами (их еще называют
операторными скобками) помещается последовательность операторов, которые выполняются в порядке следования.
З а м е ч а н и е. Нельзя извне составного оператора передавать
управление внутрь его.
Пример:
Begin
R:=5;
B:=R+2*pi;
End;
Условный оператор IF указывает, какие действия выполняются при истинности или ложности некоторого условия. Синтаксис
этого оператора следующий:
If Then Else;
Если принимает значение True, то выполняется
, иначе (при наличии Else) , расположенный за ключевым словом Else.
З а м е ч а н и е. Если при выполнении условия или его нарушении должно выполняться более одного действия, то эти действия
14

заключают в операторные скобки Begin и End и и
представляют собой составной оператор.
Пример:
If x>=0 Then begin a:=x*pi; B:=A*sqrt(x) end
Else begin A:=0; B:=exp(A); Writeln(‘A=0’) end;
Существует и короткий вариант условного оператора: без использования служебного слова Else.
Пример:
If s>1 Then s:=1;
Оператор перехода Goto. Его синтаксис следующий:
Goto ;
Этот оператор (его еще называют оператором безусловного перехода) передает управление оператору, непосредственно следующему за меткой.
Пример:
Program Enter_one;
Uses SysUtils;
Label back;
Var a:integer;
Begin
back:writeln('Enter one');readln(a);
If a1 Then Begin writeln('Mistake');Goto back End;
writeln('Correctly');readln
End.
Операторы цикла. В языке программирования Pascal имеется
три вида оператора цикла.
1. Оператор For.
For := To Do ;
Здесь переменная цикла увеличивается на единицу.
For := Downto Do ;
Здесь переменная цикла уменьшается на единицу.
Начальное и конечное значения имеют тип Integer. В теле цикла For его параметр меняться не должен. Циклы такого типа назы15

вают финитными, имея в виду то, что они всегда завершат свою работу и поэтому не могут служить причиной «зацикливания» программы.
Пример:
For i:=1 To 15 Do Begin
a:=a*I;
writeln(a:12)
End;
For i:=15 Downto 1 Do Begin
a:=I*sqrt(i);
writeln(a:12)
End;
2. Оператор While. Синтаксис этого оператора следующий:
While Do ;
Выражение имеет тип Boolean, оператор выполняется пока значение остается истинным (True) (проверка истинности осуществляется перед выполнением тела цикла).
3. Оператор Repeat.
Общий вид этого оператора следующий:
Repeat

Until ;
Тело цикла (операторы находящиеся между ключевыми словами Repeat и Until) выполняется пока значение –
False. Проверка истинности осуществляется после выполнения тела
цикла. Поэтому один раз отрабатывает в любом случае.
2.5. Массивы
Базируясь на простых типах, в языке Pascal можно строить более сложные типы переменных. Одним из таких типов является
массив – структура, состоящая из фиксированного числа компонентов одного типа. Синтаксис:
Var : array[,..,< тип индекса >] of
;
16

Пример. Описание двумерного массива с элементами целого
типа:
Var M : array[1..3, 1..4] of integer;
В этом примере первый индекс (от 1 до 3) – номер строки, второй индекс (от 1 до 4) – номер столбца:

 a11

M   a21
a
 31

a12

a13

a22

a23

a32

a33

a14 

a24  .
a34 

Обращаться к элементу массива следует так: A:=M[i,j], где
i  1..3 , j  1..4 . Переменной A присвоено значение M[i,j]. Если
записать M[i,j]:=A, то элементу массива M[i,j] присвоено значение
переменной A.
2.6. Функции и процедуры
Очень часто, почти всегда, программу следует разбивать на несколько блоков, где каждый блок может восприниматься как отдельная программа. Такое разбиение позволяет придать всей программе понятную структуру. В языке программирования Free Pascal
(Delphi) такое разбиение осуществляется с помощью процедур и
функций.
2.6.1. Процедуры
Процедура в рассматриваемом нами языке программирования
имеет ту же структуру, что и главная программа (Program): разделы Label, Const, Type, Var и выполняемую часть от Begin до End.
После слова End ставится точка с запятой в отличие от основной
программы, где ставится точка. Процедура помещается в главной
программе, после раздела описания переменных Var, перед Begin
главной программы.
В а ж н о е з а м е ч а н и е. Переменные, описанные внутри
процедуры, действуют только в самой процедуре и называются локальными переменными. Если программа содержит много переменных и много процедур, то может случиться, что локальная и глобальная переменные будут иметь один и тот же идентификатор (пе17

ременные описаны в главной программе и процедуре). При вызове
процедуры глобальный параметр временно «забывается». Когда же
процедура выполнится, то глобальная переменная принимает снова
первоначальное значение (значение, которое она имела перед выполнением процедуры). В результате никакой путаницы не происходит.
Следующее важное понятие в описании процедур – это формальные параметры. Под формальными параметрами понимаются
переменные, через которые передаются данные из программы в
процедуру либо из процедуры в программу. В качестве примера
опишем программу, вычисляющую значение функции y  a x по
формуле y  e x ln a .
Пример:
program degree;
uses
SysUtils;
var p,q,z:real;
fdeg:text;
procedure deg(a,x:real; var y:real);
begin
y:=exp(x*ln(a));
end;
begin
assignfile(fdeg,'fdeg.txt'); rewrite(fdeg);
read(p,q);
deg(p,q,z);
write(fdeg,'возводим число ',p,' в степень ',q, ' получаем ',z:12);
close(fdeg)
end.
В этой программе вызов процедуры производится оператором
deg(p,q,z), где deg – имя процедуры; p, q, z – фактические параметры. При этом устанавливается взаимно-однозначное соответствие
между фактическими и формальными параметрами, после чего
управление передается процедуре. Когда процедура закончит свою

18

работу, управление передается оператору, который следует за вызовом процедуры (в нашем случае – оператору write).
Следует подчеркнуть:
1) число фактических параметров должно быть равно числу
формальных параметров;
2) соответствующие фактические и формальные параметры
должны совпадать по порядку и по типу.
З а м е ч а н и е. Если имеется запись
Var A:array [1..25] of integer;
B:array [1..25] of integer;
то A и B считаются переменными разных типов. Поэтому при использовании массива в качестве параметра процедуры, для обеспечения совместимости, следует сначала ввести тип нужной структуры.
Пример:
Type MM=array [1..25] of integer;
Var A:MM;
Procedure P(B:MM); // Описание процедуры P
Begin
{Текст процедуры}

End;
Begin
{Текст основной программы}

P(A); // Вызов процедуры P

End;
Параметры процедур могут быть параметрами-значениями и
параметрами-переменными.
Если в качестве формального параметра указана переменная
(только параметр и его тип), то такой параметр называется параметром-значением.
Для параметров-значений машина при вызове процедур выделяет место в памяти для каждого формального параметра, вычисля19

ет значение фактического параметра и засылает его в ячейку, соответствующую формальному параметру. Если фактический параметр
есть имя переменной, то значение этой переменной пересылается в
ячейку, соответствующую формальному параметру, и далее эти параметры никак не связаны, т.е. в памяти компьютера эти параметры
занимают разные ячейки. Параметр-значение может быть константой, переменной, выражением.
Если перед именем формального параметра стоит ключевое
слово Var, то такой параметр есть параметр-переменная. В вышеприведенном примере это y:
procedure deg(a,x:real; var y:real);
Фактический параметр, соответствующий параметру-переменной, может быть только переменной (не константой, не выражением). Для параметра-переменной используется именно та ячейка, которая содержит соответствующий фактический параметр.
З а м е ч а н и е. Под формальные и фактические параметрызначения Pascal отводит разные области памяти. Поэтому результат
выполнения процедуры может быть передан только через параметрыпеременные или глобальные переменные (не рекомендуется).
2.6.2. Функции
Функция может аналогично процедуре восприниматься как отдельная подпрограмма. Но результат выполнения функции – это
всегда определенное значение.
Описание функции начинается со слова function, затем идет
имя описываемой функции, далее в скобках параметры функции по
тем же правилам, что и для процедуры, после закрывающей скобки
ставится двоеточие и пишется тип результата функции. Вышеописанный пример может быть переписан так:
program degree;
var p,q,z:real;
fdeg:text;
function deg1(a,x:real):real;
begin
deg1:=exp(x*ln(a));
end;
20

begin
assignfile(fdeg,'fdeg.txt'); rewrite(fdeg);
read(p,q);
write(fdeg,'возводим число ',p,' в степень ',q, ' получаем
',deg1(p,q):15);
close(fdeg)
end.
После заголовка, так же как и у процедур, описываются метки,
постоянные, типы, переменные и так далее. Затем между словами
begin и end следуют действия, которые вычисляют функцию.
В блоке функции обязательно должен присутствовать оператор
присваивания имени функции значения:
deg1:=exp(x*ln(a))
Сходство между процедурой и функцией заключается в том,
что в обоих случаях, используется блок-структура, при которой могут быть объявлены новые переменные, метки и т.д.
Отличие состоит в том, что значение у функции всегда должно
вычисляться. Тип этого значения должен объявляться в заголовке.
Кроме того, у функции, по крайней мере, один раз должно встречаться имя функции, стоящее слева от оператора присваивания и
выражения, из которого находится конечное значение.
З а м е ч а н и е. В качестве параметра процедуры или функции
может быть использована другая процедура или функция.
Приведем программу, вычисляющую определенный интеграл
методом средних прямоугольников:
program integral;
uses SysUtils;
type ff=function(x:real):real;//описываем тип функции
{описание функции, которая будет фактическим параметром}
function f(x:real):real;
begin f:=sqr(x) end;
{описание функции, в которой параметром является функция}
function integr(a,b:real;g:ff;n:integer):real;
var s,d,d2:real; i:integer;
begin d:=(b-a)/n; d2:=d/2; s:=0;
21

for i:=1 to n do s:=s+g(a+(2*i-1)*d2);
integr:=s*d end;
begin
{вызов функции с параметром-функцией}
writeln(integr(0,1,f,100)); readln
end.
З а м е ч а н и е. У функций, так же как и у процедур, в качестве формальных параметров могут быть параметры-переменные.
Текст программы, заключенный между фигурными скобками,
не воспринимается компьютером и там можно писать все, что угодно на любом языке. Также не воспринимается текст в правой части
строки после двух слеш. В комментариях рекомендуется указывать назначение процедур, функций, исполняемых операторов, назначение идентификаторов. Кроме того, сами идентификаторы используемых констант, переменных и меток могут быть словами,
что-то говорящими программисту, и таким образом быть неявными
комментариями. При сложной структуре программы, когда одни
блоки вложены в другие, разумно начало и конец каждого из блоков
помечать одинаковым комментарием и тогда будет видно, какой
именно End соответствует какому Begin.

3. РЕАЛИЗАЦИЯ НЕКОТОРЫХ МАТЕМАТИЧЕСКИХ
АЛГОРИТМОВ СРЕДСТВАМИ FREE PASCAL
3.1. Произведение матриц
Пусть даны две матрицы

 a11

 a21
A


a
 m1

a12
a22

am 2

 b11 b12

 b21 b22
B
 

 bn1 bn 2


a1n 

 a2n 
и
 

 amn 


 b1 p 

 b2 p 
,
 

 bnp 

причем число столбцов матрицы A равно числу строк матрицы B .
Произведением матрицы A на матрицу B называется матрица C ,
22

 c11 c12

 c21 c22
C 
 

 cm1 cm 2


 c1 p 

 c2 p 
,
 

 cmp 

обозначаемая через AB , элементы которой вычисляются по формулам
n

cij   ais bsj , где i  1,2,, m ; j  1,2,, p .
s 1

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

p

n
m

n

p
m

Программа, перемножающая две матрицы представленные в
файле, записывается в виде
Program multiplication_matrix;
var m,n,p:integer;
A,B,C:array [1..20,1..20] of double;
i,j,s:integer;
ABC_MAT:text;
begin
//параметры и исходные матрицы читаем из файла, туда же
//записываем результат произведения. Считаем, что размерности
//файлов удовлетворяют правилу произведения матриц
assign(ABC_MAT,'c:\fpc\ABC_MAT.txt'); reset(ABC_MAT);
//читаем параметры матриц
read(ABC_MAT,m,n,p);
//читаем матрицу А
for i:=1 to m do
23

for j:=1 to n do read(ABC_MAT,A[i,j]);
//читаем матрицу B
for i:=1 to n do
for j:=1 to p do read(ABC_MAT,B[i,j]);
//находим произведение матриц – матрицу C
for i:=1 to m do
for j:=1 to p do begin
C[i,j]:=0;
for s:=1 to n do
C[i,j]:=C[i,j]+A[i,s]*B[s,j]
end;
//выводим результат в тот же файл
close(ABC_MAT);
append(ABC_MAT);
writeln(ABC_MAT);
writeln(ABC_MAT,'result');
for i:=1 to m do begin
for j:=1 to p do write(ABC_MAT,C[i,j]:12,' ');
writeln(ABC_MAT)
end;
close(ABC_MAT)
end.
3.2. Вычисление определителя квадратной матрицы

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

P  a1 a2  an .

24

(3.1)

Первый индекс у сомножителя aij в произведении (3.1) соответствует номеру строки, второй – номеру столбца. Номера столбцов при упорядоченности по номерам строк дают перестановку
(, ,, ) . Если эта перестановка четная, то величина P , входящая в определение определителя, берется со знаком плюс, если нечетная – то со знаком минус.
З а м е ч а н и е. Непосредственное вычисление определителя
по определению представляет собой трудоемкий процесс, так как
нужно находить n! произведений и выбрать знак каждого из них.
Но можно заметить, что если все элементы, стоящие выше или ниже главной диагонали равны нулю, то определитель равен произведению элементов, стоящих на этой диагонали: a11a 22  a nn .
Полезными при вычислении определителей оказываются следующие их свойства:
 определитель матрицы n-го порядка не изменится, если к
элементам одной ее строки прибавить соответствующие элементы
другой строчки этой же матрицы, умноженной на одно и то же произвольное число;
 если все элементы какой-нибудь строчки матрицы n-го порядка умножить на число c , то ее определитель также умножится
на число c ;
 перестановка двух строк в матрице определителя приводит к
изменению знака определителя.
Из сделанного замечания и перечисленных свойств следует, что
матрицу определителя целесообразно привести к треугольному виду и найти произведение элементов, стоящих на главной диагонали.
При этом перед процедурой диагонализации следует матрицу определителя привести к виду, при котором на главной диагонали будут
стоять ненулевые элементы (напомним, что перестановка строк меняет знак определителя).
Программа, реализующая сказанное, имеет следующую запись:
Program Determinant;
var n,i,j,k,kk:integer;
DetA,dd,p:double;
A,B:array [1..20,1..20] of double;
F_det:text;
25

begin
assignfile(F_det,'F_det.txt'); reset(F_det);
//input n - dimension of determinant
read(F_det,n);
//read matrix
for i:=1 to n do
for j:=1 to n do begin read(F_det,A[i,j])
end;

closefile(F_det); append(F_det); writeln(f_det);
writeln(f_det,n); writeln(f_det);
//Проверка введенной матрицы
for i:=1 to n do begin
for j:=1 to n do write(F_det,A[i,j]);
writeln(f_det)
end;
dd:=1;
//установка на главной диагонали ненулевых элементов
//При этом учитывается знак при перестановке строк в опреде//лителе, вначале dd=1, а при перестановке dd меняет знак
for i:=1 to n-1 do
if (A[i,i]=0) then begin
j:=i+1;
while((A[j,i]=0) and (j