TURBO PASCAL |
Новости
|
Выпуск № 3 - Как написать неработоспособного монстра ?
Венгерская нотацияВ современном программировании используется такой способ формирования имен идентификаторов. Говорят, что такой удобный и информативный способ написания имен придумал сотрудник компании Microsoft программист венгр по национальности Чарльз Симони. Суть заключается в том, что первые буквы имени являются значащими и указывают на тип переменной (константы), остальная часть - имя, идентифицирующая роль переменной в программе. Одно из удобств заключается в том, что имя переменной данного типа формируется простым отбрасыванием первых символов. Второе - не надо вспоминать, что это за переменная такая? Какого она типа? Особенно в случае, когда Вы будете придерживаться одной системы обозначений.В Паскале часто используются два префикса: T - для идентификатора ТИПА (Type), и P - для идентификатора указателя в памяти (Pointer). Например: TYPE PSomeType = ^TSomeType; {создается указатель на переменную типа TSomeType} TSomeType = record {новый тип переменной - запись с заданными полями} Name: String[20]; Age : Byte; end;В дальнейшем я буду широко пользоваться такими обозначениями. А так ... . Можно определить константу с именем constValue или cValue, которые содержат часто используемое значение переменной Value. Тогда присваивание Vakue:=cValue; выглядит и понятным и естественным. Способы защиты переменныхВ предыдущем выпуске я обещал показать, как можно, не используя объектов, отслеживать, какое значение пользователь хочет записать в мою переменную. Пожалуйста …Существует два простых способа защиты переменной от этих пользователей: (1) размещением переменной в разделе реализаций модуля; и (2) использование типизированных констант внутри подпрограммы. Используем свойства модулей Исходный текст программы должен состоять из двух файлов. Первый - основной. Назовем его Main.pas. Второй файл - модуль, который назовем Prtct.pas. Ниже их текст: Program Main; uses Crt, Prtct; BEGIN SetValue(-12); SetValue(127); WriteLn('Hidden = ',GetValue); { Hidden:=2; } ReadKey END. unit Prtct; interface procedure SetValue(AValue: Integer); function GetValue: Integer; implementation VAR Hidden: Integer procedure SetValue; begin if AValue < 0 then begin Writeln('Попытка записать недопустимое значение: ',AValue); Exit End; Hidden:= AValue; end; function GetValue: Integer; begin GetValue:=Hidden end; END.Запускать программу из среды разработки программа Borland Pascal нужно находясь в окне главной программы, или нужно установить "первичный файл" с помощью пункта меню Compile &right; Primary file…. Попробуйте из программу (main.pas) изменить так, чтобы прочитать, переменную Hidden. Закомментированный текст в программе и пытается делать это. Вроде бы задача решена. Но … есть два недостатка по сравнению с объектами.
Используем типизированные константы procedure WithMyVar(var PrevValue: Integer; NewValue: Integer); const MyValue: Integer = 0; begin PrevValue:=MyValue; if NewValue < 0 then begin Writeln('Попытка записать недопустимое значение: ', NewValue); Exit end; MyValue:=NewValue end;Надеюсь, протестировать работу процедуры сможете сами. А теперь обратите внимание: эта процедура имеет собственную переменную, словно объект, но объект, поверьте пока на слово, делает это элегантнее! И еще: нельзя просто прочитать значение переменной-константы MyValue. Существует "запаздывание". [ в начало ] Пример объекта, хранящего информацию в файлеЭтот объект производит "циклическое" чтение строк из текстового файла. То есть, если файл прочитан до конца, то опять читается первая строка. Я не буду подробно комментировать код сейчас. ЭТО ВЕДЬ ИДЕЯ ООП: пользователь и не должен знать, как сложно все реализуется!Отмечу только важное: 1) предполагается что этот код сохранен в файл B.pas. Впрочем,
если не так, то только получите сообщение об ошибке; 2) в объекте есть метод,
который следует вызывать самым первым program SecondObj; uses CRT; const cFileName = 'B.pas'; cmodeOk = 0; cmodeFail = -1; cmodeFirst = 1; cmodeEOF = 10; TYPE TFileString = object procedure CallThisFirst; function First: String; function Next : String; procedure CallThisLast; private fText: Text; fMode : Integer; procedure OpenFile(FileName: String); end; procedure TFileString.CallThisFirst; begin ClrScr; fMode:=cmodeFirst; end; function TFileString.First: String; var Buf: string; begin Buf:=''; case fMode of cmodeOk : ReadLn(fText,Buf); cmodeFirst: begin OpenFile(cFileName); Buf:=First end; cmodeFail : WriteLn('Ошибка при открытии файла'); cmodeEOF : begin Reset(fText); Buf:=First end; end; First:=Buf end; function TFileString.Next : String; var Buf: String; begin if fMode = cmodeOk then if NOT EOF(fText) then begin ReadLn(fText, Buf) end else begin fMode:=cmodeEOF; Buf:=First end; Next:=Buf; end; procedure TFileString.CallThisLast; begin if fMode = cmodeOk then Close(fText) end; procedure TFileString.OpenFile(FileName: String); begin if fMode = cModeOk then Close(fText); Assign(fText,FileName); {$I-} Reset(fText); {$I+} if IOResult = 0 then fMode := cmodeOk else fMode := cmodeFail; end; VAR F: TFileString; i: Integer; BEGIN F.CallThisFirst; WriteLn(F.First); for i:=1 to 20 do WriteLn(F.Next); F.CallThisLast; END.[ в начало ] Оцените "стандартный" объектВ Borland Pascal создана система Turbo Vision. С ее помощью Вы относительно легко можете писать программы с интерфейсом, подобным интерфейсу (меню, строка статуса, система команд, окон, ...) среды разработки программ (редактор) Borland Pascal. Сейчас изучать его нет необходимости. В Delphi, например, все это делается и лучше и быстрее. (Хотя принцип тот же!). В системе Turbo Vision есть несколько модулей, которые содержат очень полезные объекты, которые можно использовать вне системы. Например, в модуле Objects имеется объект TStringCollection, который готов для хранения коллекции строк. Сейчас я только покажу, как его использовать для хранения строк, прочитанных из файла.Следующий код сохранен под именем «strcol.pas». И ошибка не отрабатывается! Такое поведение естественно. Для объекта неважно, откуда берутся строки. Если для пользователя важна правильная работа в любом случае, то нужно объяснить объекту, что мы хотим от него. Дополнить его функциональные возможности. Сейчас только попробуйте. Вы увидите в тексте программы много новых слов. Одно интуитивно понятное слово «virtual» чего стоит! Все объяснять буду позднее - и так я до безобразия затянул работу над выпуском. Для одного сделаю исключение, для команды, которая помещает прочитанную строку в коллекцию StrCol.Insert(NewStr(S+' '));. Коллекция хранит не строки, а указатели на строки, размещенные в динамической памяти программы. Помещает их туда функция NewStr, которая плохо работает, если строка пустая. Вот я и добавляю на всякий случай пробел. program StrCol; uses CRT, Objects; TYPE TMyStr = object(TStringCollection) function Compare(Key1, Ke2: Pointer): Integer; virtual; end; function TMyStr.Compare(Key1, Ke2: Pointer): Integer; begin Compare:=-1 end; VAR StrCol: TMyStr; T: Text; i: Integer; S: String; BEGIN Assign(T, 'strCol.pas'); Reset(t); StrCol.Init(10,5); while NOT eof(t) do begin ReadLn(t,s); StrCol.Insert(NewStr(S+' ')); end; for i:=0 to StrCol.Count - 1 do Writeln(PString(StrCol.At(i))^); Readkey; StrCol.Done; END. © Борис Сурин |
(с)Все права защищены По всем интересующим вопросам прошу писать на электронный адрес |