Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Мансуров. Основы программирования в среде Lazarus. 2010

.pdf
Скачиваний:
45
Добавлен:
27.04.2021
Размер:
6.3 Mб
Скачать

Глава 3 Более сложные элементы языка

____________________________________________________________________

writeln('');

for i:=0 to n-1 do

writeln('x', i+1, '= ', x[i]:0:4); end

else

if b[n-1] = 0 then writeln(UTF8ToConsole('Система не имеет решения.'))

else

writeln(UTF8ToConsole('Система уравнений'+ ' имеет бесконечное множество решений.'));

writeln(''); {освобождение памяти,

распределенной для динамического массива} a:=nil;

end;

{Начало основной программы} begin

{Ввод коэффициентов расширенной матрицы} writeln(UTF8ToConsole('Введите количество неизвестных')); readln(n);

{Установка реальных размеров динамических массивов} SetLength(a, n, n);

SetLength(vector, n*n); SetLength(b, n); SetLength(x, n);

{в динамических массивах индексы начинаются с нуля} for i:=0 to n-1 do

begin

for j:=0 to n-1 do begin

writeln(UTF8ToConsole('Введите a'), i+1, j+1); readln(a[i,j]);

end;

writeln(UTF8ToConsole('Введите b'), i+1); readln(b[i]);

end;

{Преобразование двумерного массива в одномерный} k:=1;

for i:=0 to n-1 do for j:=0 to n-1 do begin

vector[k]:=a[i,j];

211

3.4 Массивы

____________________________________________________________________

k:=k+1;

end;

{Вызов процедуры решения системы линейных алгебраических уравнений методом Гаусса} gauss(vector, b, x, n); {освобождение памяти, распределенной для динамических массивов} a:=nil;

vector:=nil;

x:=nil;

b:=nil;

writeln(UTF8ToConsole('Нажмите любую клавишу')); readkey;

end.

Обратите внимание, что массив "a" в главной программе и массив "a" в проце-

дуре это разные массивы, в том смысле, что они будут при выполнении про-

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

мерный массив преобразуется обратно в двумерный массив с именем "а".

В принципе, можно реализовать алгоритм и с одномерным массивом,

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

грамму. Организуйте ввод коэффициентов системы сразу в одномерный дина-

мический массив и реализуйте с ним алгоритм метода Гаусса.

Общим недостатком всех трех программ является отсутствие контроля при вводе коэффициентов системы. Однако это сделано намеренно, чтобы не отвле-

каться от сути задачи и не загромождать программы излишними деталями.

Программы и так получаются достаточно большими. Вы можете самостоятель-

но вставить проверку при вводе, используя способы, изложенные в 2.1.25. Бо-

лее продвинутые и профессиональные способы контроля мы будем рассматри-

вать в главе 6.

212

Глава 3 Более сложные элементы языка

____________________________________________________________________

3.5. Модули в Паскале

Модуль это такая программная единица, которая может и, чаще всего,

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

дур, а также константы, переменные, объявленные типы. Это позволяет разде-

лить работу между программистами при разработке больших и сложных про-

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

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

ров, как правило, занимается руководитель проекта.

При этом каждый программист пишет и отлаживает свой модуль незави-

симо от других.

Текст модуля на языке программирования называется исходным модулем.

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

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

дур. Например, главная программа вызывает некую функцию из модуля А, в

модуле В происходит вызов процедуры из модуля С и т.д. Такой процесс назы-

вается разрешением связей. В итоге собирается исполняемая программа.

3.5.1 Структура модуля

Структура модуля имеет вид:

213

3.5 Модули в Паскале

____________________________________________________________________

unit <Имя модуля>;

 

interface

//

раздел интерфейса

<раздел открытых описаний>

implementation

//

раздел реализации

<раздел закрытых описаний>

initialization

// раздел инициализации

finalization

// раздел завершения

end.

 

 

Модуль начинается со служебного слова unit, за которым следует имя модуля. В случае если данный модуль использует другие модули, после слова interface необходимо поместить служебное слово uses и список исполь-

зуемых модулей.

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

процедуры и функции, которые доступны для всех программ и модулей, ис-

пользующих данный модуль. Глобальные переменные, помещенные в интер-

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

Раздел реализации модуля начинается служебным словом implementation. В секции реализации могут находиться свои описания, не-

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

ции являются видимыми в секции реализации.

Те процедуры и функции, которые описаны в интерфейсной секции, опи-

сываются еще раз в секции реализации, причем их заголовок должен быть точ-

но таким же, как тот, который указан в секции интерфейса.

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

214

Глава 3 Более сложные элементы языка

____________________________________________________________________

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

граммы. При использовании нескольких модулей, их секции инициализации вызываются в порядке, указанном в uses. Секция инициализации является не-

обязательной и может вообще отсутствовать.

Раздел finalization также является необязательным. В нем выполня-

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

С целью уменьшения размера основной программы, улучшения читабель-

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

Имя библиотечного модуля должно совпадать с именем файла, под кото-

рым хранится текст модуля на диске. Исходный текст библиотечного модуля имеет расширение *.pas (<имя модуля>.pas).

В качестве примера оформим программу вычисления синуса из раздела

3.1.1.3 в виде модуля.

В меню Файл выберите пункт Создать модуль. В окне редактора исходного кода появится заготовка кода для модуля. Очистите окно редактора и введите текст модуля:

unit my_module;

interface

function No_standard_sin(x:real):real;

implementation

{повторяем заголовок функции точно таким

что и в разделе interface}

function No_standard_sin(x:real):real;

var eps,s,t: real;

215

3.5 Модули в Паскале

____________________________________________________________________

n: integer; begin

s:= x; t:= x; n:= 2; eps:= 1e-7; repeat

t:= -t * (sqr(x)/(n * (n + 1))); s:= s + t;

n:= n + 2; until abs(t)< eps;

No_standard_sin:= s; end;

end.

Сохраните модуль обязательно с тем же именем, что указан в заголовке модуля, т.е. my_module.pas в какой-нибудь папке. Откомпилируйте модуль на-

жав клавиши Ctrl+F9 или меню Запуск-> Собрать. Для каждого модуля созда-

ются два файла: двоичный файл описания модуля с расширением (.ppu) и объ-

ектный с расширением (.o). Таким образом, в вашей папке создадутся два файла my_module.ppu и my_module.o

Создайте консольное приложение и введите текст программы:

program project_with_my_module; {$mode objfpc}{$H+}

uses

CRT, FileUtil,SysUtils, my_module; // указываем имя модуля var x, y, dx: real;

begin x:= 0;

dx:= 0.1; while x <= 1 do

begin

216

Глава 3 Более сложные элементы языка

____________________________________________________________________

y:= No_standard_sin(x);

writeln('x= ', x:0:1, ' y= ', y:0:7,

' sin(x)= ', sin(x):0:7);

x:= x + dx;

end;

writeln(UTF8ToConsole('Нажмите любую клавишу'));

readkey;

end.

Сохраните проект в той же папке, где вы сохранили модуль или скопируй-

те файлы my_module.ppu и my_module.o в папку с текущим проектом. Нажмите клавишу F9. Начнется компиляция и сборка (компоновка) программы. На этапе сборки ваш модуль будет автоматически добавлен в исполняемую программу.

После выполнения программы вы получите те же самые результаты, что и в разделе 3.1.1.3.

Если вы хотите, чтобы ваш модуль был доступен и в других программах,

то проще всего поступить следующим образом:

1.Создайте папку, например с именем my-units

2.Перенесите в эту папку файлы my_module.ppu и my_module.o;

3. Скопируйте саму папку my-units в системный каталог

"C:\lazarus\fpc\2.2.4\units\i386-win32" если вы работаете в Windows или в ката-

лог "/usr/lib/fpc/2.2.4/units/i386-linux", если вы работаете в Linux.

Теперь ваш модуль будет автоматически подключаться в ваши программы

(разумеется, надо прописать имена модулей в объявлении uses). Почему именно в этот каталог? Потому что компилятор если не найдет модуль в папке с вашим проектом, он будет искать его по умолчанию в этой системной папке.

Если же вы разместили папку my-units в другом месте, то вам придется прописывать путь к этой папке, либо в инспекторе проекта, либо непосредст-

венно в объявлении uses вот таким образом:

uses my_module in '<путь к папке с исходным кодом модуля>'

217

3.5 Модули в Паскале

____________________________________________________________________

Другой способ – это добавить путь к модулю в файле fpc.cfg. Файл на-

ходится в папке \lazarus\fpc\2.2.4\bin\i386-win32 в Windows или в папке /etc в Linux. Найдите в этом файле строку

# searchpath for units and other system dependent things

И добавьте запись вида:

-Fuпуть к модулю (именно без пробела!), например

-Fuс:\my-projects\my-units\ (Windows)

-Fu/home/user/my-projects/my-units (Linux)

Но этот файл системный, "лезть" в него без особой необходимости не ре-

комендую.

В предложенном мною способе "ничего не надо делать"! Надо просто ско-

пировать папку my-units в системный каталог. Путь к нему уже прописан в файле fpc.cfg. Только чтобы не "замусоривать" системный каталог, вам нужно все свои модули, сколько бы их ни было, помещать только в одну папку, в на-

шем случае мы будем размещать все наши общие модули в папку my-units.

3.5.2 Системные модули

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

ров. Рассмотрим вкратце некоторые системные модули:

System – содержит стандартные функции и процедуры "классического"

Паскаля, например, вычисления функции cos, sin, ln, exp и др. Модуль

218

Глава 3 Более сложные элементы языка

____________________________________________________________________

System автоматически доступен всем программам. Фактически мы широко пользовались этим модулем.

DOS- содержит процедуры и функции, позволяющие использовать средст-

ва операционной системы MS-DOS.

CRT – набор процедур для работы с экраном и клавиатурой.

Graph – содержит обширный набор программ, который позволяет исполь-

зовать графические возможности компьютера.

В настоящее время этот модуль устарел и практически не используется.

Логика его работы слабо совместима с современными системами и проблем с ним уйма. Начинающие часто находят какие-то примеры с его использованием и разочаровываются - часть не работает вообще, в Linux возникают проблемы с библиотеками, правами доступа и т.д.

Для использования модуля достаточно в программе после строки заголов-

ка вставить строку:

uses имя модуля;

Если используется несколько модулей, то пишется так:

uses имя модуля 1 , имя модуля 2, ….., имя модуля N;

Просмотреть тот или иной системный модуль можно, нажав клавишу

Ctrl и одновременно подведя указатель мыши к имени модуля. Когда имя мо-

дуля заменится на гиперссылку, нажмите на левую клавишу мыши.

В частности, если вы посмотрите модули SysUtils, FileUtil,

LCLProc и др., то увидите там объявления и реализации тех функций и проце-

дур, которыми мы широко пользовались.

Рекомендую почаще заглядывать в эти и другие системные модули. Вы

219

3.5 Модули в Паскале

____________________________________________________________________

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

3.5.2.1. Модуль CRT

Модуль CRT, как уже говорилось, содержит ряд процедур и функции для работы с экраном в текстовом режиме, клавиатурой и динамиком. Замечу, что этот модуль оставлен для совместимости с Turbo Pascal. В настоящее время программисты чаще используют другие средства.

Рассмотрим экран компьютера в текстовом режиме. Обычно на нем раз-

мещается 25 строк текста и 80 символов в каждой строке. Для того чтобы пол-

ностью владеть экраном, нужно знать координаты курсора, менять цвет симво-

лов, текста и фона. Для этого существуют следующие процедуры:

GoToXY(i,j)- позиционирует курсор в i строку и j столбец экрана.

write(s)- выводит строку s начиная с текущей позиции курсора.

процедура TextColor(Color)- устанавливает цвет выводимого текста.

Существуют следующие константы цветов:

Black - черный;

Blue - синий;

Green - зеленый;

Cyan - бирюзовый;

Red - красный;

Magenta - малиновый;

Brown - коричневый;

LightGray - светло-серый;

DarkGray - темно-серый;

LightBlue - ярко-голубой;

LightGreen - ярко-зеленый;

220