#1E Модули

Сегодня в выпуске:

Вступление

Здравствуйте!
Давненько у нас не было 2-х выпусков в неделю. Что же на этой неделе мы компенсируем этот недостаток. К тому же приятно из мира Ассемблера наконец-то вернуться к "родному" Пакалю. Наслаждайтесь!

Новости сайта

Во первых хочу покаятся за ошибку со ссылкой, наверняка многие хотели скачать книгу Б.Гейтса. Ссылка к сожалению вела в никуда :( Вот эта правильная: http://www.web-pascal.narod.ru/doc/ROAD.zip. Ещё раз приносим свои извинения.

[01.03.03] В раздел Статьи добавлена статья:" Как работать с мышкой".

В статье приводится описание функций прерывания INT 33h. Через которое можно обратиться к более чем двум десяткам функций манипулятора мышь. Это описание скомпилировано из фольклорных файлов MOUSE.DOC, INTERRUP.LST и личного опыта работы автора.
(Автор: Alexander Rusanovsky)
http://www.web-pascal.narod.ru/stat/int33h.htm

Теория

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

Модули так же полезны, если код не влезает в 64 Кб (это актуально только для ДОС программ), т.к. компилятор Турбо Паскаля загоняет текст модуля в отдельный сегмент.

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

UNIT имя;
INTERFACE
интерфейсная часть
IMPLEMENTATION
исполняемая часть
BEGIN
часть инициализации
END.
Начнём по порядку. ИМЯ - задаёт имя модуля (это то, которое мы потом будем объявлять в USES). Для того что бы избежать лишних проблем следует называть модуль и файл с его кодом одним именем. Т.е. если мы хотим назвать модуль так:
unit myunit;
то текст его должен распологаться в файле с именем myunit.pas.

Интерфейсная часть несёт в себе описание типов, переменных, констант, подпрограмм, которые можно будет использовать (вызывать) из головной программы. При описании подпрограмм нужно написать просто их заголовок. Например начнём писать простенький модуль для работы с комплексными числами. (для тех кто в танке - комплексные числа - это числа вида a + b*i, где i число, такое что i2 = -1, a и b - вещественные числа... вообщем литературу на эту тему найти легко, было бы желание). Для этого опишем запись с полями re и im (это a и b) и заголовок процедуры для сложения 2-х комплексных чисел.

unit Cmplx;
interface
type
   complex = record
       re, im : real;
   end;

 procedure AddComplex (x, y : complex; var z : complex);
Итак теперь в основной программе, подключив наш модуль, мы можем объявить переменные типа complex и вызывать процедуру AddComplex. Следует так же отметить (ведь наши программы пока для ДОСа), что все переменные объявленные в интерфейсной части модуля и все переменные основной программы помещаются в единный сегмент данных и следовательно не могут превышать 64 Кб.

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

unit Cmplx;
interface
	type
	   complex = record
		   re, im : real;
	   end;

	 procedure AddComplex (x, y : complex; var z : complex);
 implementation

	 procedure AddComplex;
	 begin
	   z.re := x.re + y.re;
	   z.im := x.im + y.im
	 end;
Обратите внимание на объявление процедуры AddComplex в исполняемой части модуля. Очередная халява - можно опускать список параметров (и тип результата для функции), так как они уже описаны в интерфейсной части. При этом халява не обязательная - вы вполне можете написать полный заголовок.

Переходим к последней части - части инициализации. Она может быть, а может и не быть. Если она есть - тогда обрамляется begin-end. Если её нет, тогда просто пишется end. (с точкой!!). В части инициализации помещается код, который выполняется до передачи управления главной программы. Например здесь программист может присвоить переменным модуля какие-то стартовые значения. В нашем модуле нет никаких тайных махинации и поэтому мы можем опустить инициализацию и вот он - наш первый законченный модуль:

unit Cmplx;
interface
	type
	   complex = record
		   re, im : real;
	   end;

	 procedure AddComplex (x, y : complex; var z : complex);
 implementation

	 procedure AddComplex;
	 begin
	   z.re := x.re + y.re;
	   z.im := x.im + y.im
	 end;
end.
Ещё один важный момент - если нечего инициализировать, то тогда лучше вообще не писать часть инициализации (т.е. слово begin) т.к. получится так называемый пустой оператор. Что может в некоторых случаях привести к проблемам.

Давайте напишем модуль с инициализацией и скрытой переменной:

unit some;

interface

procedure iplus;

implementation

uses CRT;

var
  i : integer;

procedure iplus;
begin
  i := i + 1;
  writeLn ('I = ', i)
end;

begin
   randomize;
   i := random (256);
   writeLn ('Start I = ', i)
end.
i - это переменная, доступная только внутри модуля! Тепрь напишем головную программу, использующую этот самый модуль:
program test;

uses some;

begin
  writeLn ('Yo-ho-ho!');
  iplus;
  iplus;
  iplus
end.
Запускаем и что мы видим?
Start I = 16
Yo-ho-ho!
I = 17
I = 18
I = 19
О чём нам говорит эта картинка? Правильно: о том, что часть инициализации модуля выполнится раньше чем головная программа. Вот вообщем то и всё.

Программа

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

unit mouse;

interface

const
  MB_LEFT   = 1;
  MB_RIGHT  = 2;
  MB_MIDDLE = 4;

type
  tPoint = record
           x, y : integer
  end;
  tMouseState = record
                 loc:tPoint;
                 but:integer
  end;

function  ResetMouse:integer;
procedure ShowMouse;
procedure HideMouse;
procedure GetMouseState (var s:tMouseState);
procedure MoveMouseCursor (p :tPoint);
procedure SetMouseVert (max, min : integer);
procedure SetMouseHorz (max, min : integer);

implementation

function  ResetMouse:integer;assembler;
asm
    xor ax, ax
    int 33h
end;

procedure ShowMouse;assembler;
asm
  mov ax, 1
  int 33h
end;

procedure HideMouse;assembler;
asm
  mov ax, 2
  int 33h
end;

procedure GetMouseState;assembler;
asm
  mov ax, 3
  int 33h
  push es
  push di
  les di, dword ptr s
  mov es:[di], cx
  mov es:[di+2], dx
  mov es:[di+4], bx
  pop di
  pop es
end;

procedure MoveMouseCursor;assembler;
asm
  mov ax, 4
  mov cx, p.x
  mov dx, p.y
  int 33h
end;

procedure SetMouseVert;assembler;
asm
 mov ax, 8
 mov cx, min
 mov dx, max
 int 33h
end;

procedure SetMouseHorz; assembler;
asm
 mov ax, 7
 mov cx, min
 mov dx, max
 int 33h
end;

end.
Итак наш модуль поддерживает всего 7 из 31 возможных функций мыши. Если хотите ознакомится, то в новостях сайта дана ссылка на соответствующий документ.

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

Мы имеем общедоступными 3 константы - они определяют кнопки мыши. 2 типа:

  • tPoint - описывает точку на экране
  • tMouseState - описывает состояние мыши. loc - координаты, but - состояние кнопок (имено те 3 константы).
И наконец 6 подпрограмм:
  • function ResetMouse:integer;
    Инициализирует мышь, если таковой не имеется вернётся нулевое значение.
  • procedure ShowMouse;
    Показывает курсор мыши на экране. При этом курсор следует за перемещениями мыши.
  • procedure HideMouse;
    Прячет курсор. Полезно когда надо что-то нарисовать под курсором, последовательность действий при этом: спрятали курсор, нарисовали, показали курсор.
  • procedure GetMouseState (var s:tMouseState);
    Читает и возвращает состояние мыши в виде записи tMouseState
  • procedure MoveMouseCursor (p :tPoint);
    Передвигает курсор мыши в точку p
  • procedure SetMouseVert (max, min : integer);
    Устанавливает минимальную/максимальную вертикальную границу передвижения мыши
  • procedure SetMouseHorz (max, min : integer);
    Устанавливает минимальную/максимальную горизонтальную границу передвижения мыши
Никаких скрытых подпрограмм или переменных у нас нет. Секция инициализации так же опущена, за ненадобностью.

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

program mousetest;

uses graph, mouse, crt;

var
 Gd, Gm: Integer;
 flag : boolean;
 ms : tMouseState;

begin
  Gd := Detect;
  flag := false;

  InitGraph(Gd, Gm, '');

  if GraphResult <> grOk then
    Halt(1);

  Randomize;
  ShowMouse;

  while not flag do
  begin
    GetMouseState (ms);

    if ms.but = MB_RIGHT then
        flag := true
    else if ms.but = MB_LEFT then
       PutPixel (ms.loc.x - 1, ms.loc.y - 1, Random (WHITE))
  end;

  CloseGraph
end.
Итак мы в цикле опрашиваем мышь, если нажата правая кнопка (ms.but = MB_RIGHT), тогда выходим из программы. Если нажата левая кнопка, тогда ставим точку случайного цвета на экране. Вот и всё!.

Голосование

Три дороги
На моем пути,
Три тревоги -
Что там впереди?
Три вопроса,
И одна петля,
Где лежит дорога моя?

Моё повествование о Паскале подходит к концу, ещё 3-4 выпуска непосредственно про Паскаль и пару выпусков про графику. И поэтому надо думать: что дальше? Мои варианты:
  • Изучение Object Pascal - расширение Паскаля до объектно ориентированного языка. Именно на нём основан Delphi. Освоить его очень просто, тем более что осваивать будем на том же BP 7.
  • Изучение программирования под Windows. Не на Delphi - а именно на Паскале. Тут пойдет конкретное повествование об особенностях построения пользовательского интерфейса - вообщем как создавать окна, отдельные элементы и т.п. Можно было бы изучить и на BP 7, но лучше будет использовать какой-либо 32-х разрядный компилятор, так что возможно придётся что-то и скачать.
  • Писать про реализацию различных алгоритмов, не привязываясь к какой-либо ОС. Самые различные алгоритмы - понемногу (или многу) обо всём.
  • Или четвёртая дорога - одобрить мой план: сначала Object Pascal, потом Windows, потом немного о Delphi, а потом уже алгоритмы.
Если есть другие предложения - просьба не стесняться - пишите.

Проголосовать и посмотреть как это сделали другие можно по этой ссылке: http://narod.yandex.ru/survey/?id=96923

Это должен посетить каждый!

Уж полночь близится, а Германна всё нет.
Цитата для сетевой игры "Червы"

Мда. Продолжаем опустошать мои ссылки:
  • http://pasc.al.ru/ - в моём списке значится, как Turbo Pascal Site. Насколько мне помнится там была хорошая коллекция исходников и давненько не было обновления.
  • http://www.ipg.h1.ru - "Дистанционное обучение программистов" - содержит множество незаконченных туториалов по программированию на С, Паскале, PHP, задачам, PhotoShop... пополнение и новые выпуски происходят раз в месяц или реже.
  • http://prog.km.ru/dokumentaciya/bsp/index.php "Библиотека системного программиста". Из серии это должно быть у каждого :) Несмотря на то, что все программы написаны на С это просто классика, да ещё на русском языке (вам ведь влом читать англоязычную документацию). Вообщем ужастно полезные в хозяйстве книги. Эх если б было такое для Паскаля :(
  • http://www.netlib.wallst.ru/ - Сетевая библиотека - сайт, на котором размещаются различные книги. Если вы хотите изучить Ассемблер, то обязательно скачайте оттуда бестселлер Зубкова "Ассемблер для DOS, Windows и Unix" - по праву считающейся одной из лучших книг про программирование на этом языке. Будем ждать книг про Паскаль...
  • http://www.exler.ru/novels/wife.htm - ну и на последок юмор - "Записки невесты программиста"... :) главное не зачитаться до утра :)))

[Назад] [Содержание] [Дальше]
Hosted by uCoz