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.
© Борис Сурин |
|
(с)Все права защищены По всем интересующим вопросам прошу писать на электронный адрес |