Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Implementation




Interface

Рис- 32

Программа приведена ниже.

unit priml2;

uses Windows, Messages, SysUtils, Classes, Graphics, Forms,

Controls, Dialogs, StdCtrls, Buttons, ComCtrls, ExtCtrls; type

TMainForm = class(TForm) TabControll: TTabControl; Bevel1: TBevel;

Panel1: TPanel;

Button1: TButton;

BitBtnl: TBitBtn;

Label2: TLabel;

procedure Button1Click (Sender: TObject); procedure TabContxollChange (Sender: TObject); end;

const k=30; L=200; mn=set of 0..L;


 


var MainForm: TMainForm;

s:array [0..2] of mn;

ss:array [0..2] of mn=([25],[50],[100]);

{$R *.DFM}

procedure TMainForm.Button1Click (Sender: TObject);

var i,j,z:byte; begin

randomize;

for j:=0 to 2 do

repeat

s[j]:=[]; for i: = l to к do

while true do begin z:=random(L+l); if z in s[j] then continue;

include(s[j], z);

break;

end;

until ss[j]<=s[j];

end;

procedure TMainForm.TabControllChange {Sender: TObject); var Canvas:TCanvas; str:string; i,j:byte;

begin

try

Canvas:=TCanvas.Create; try

Canvas.Handle:=GetDC((Sender as TTabControl).Handle); with (Sender as TTabControl) do begin Canvas.Brush.Color:=clWhite; Canvas.FillRect(DisplayRect); Canvas.Font.Color:=clRed;

str: = "; j:=0;

for i:=0 to L do begin

if i in s[TabIndex] then str:=str+IntToStr(i)+' ';

if (i mod 20 = 0) and (length(trim(str))>0) then begin

with DisplayRect do Canvas.TextOut(left+

Font.Size,top-j*font.Heightsj,str);

str:=’';

inc(j);

end;

end;

end;

finally

ReleaseDC((Sender as TTabCotrol).Handle,Canvas.Handle);


end; finally

Canvas.free; end; end; end.

Для создания канвы в клиентской области компонента TTabControl объявлена переменная canvas типа TCanvas. Создание экземпляра данного типа осуществляется с помощью процедуры create (эта процедура является конструктором). После выполнения определенных действий следует освобо­дить занимаемую канвой память, когда канва не будет нужна, с помощью процедуры Free, называемой деструктором. Вывод на канву, в данном слу­чае, текста осуществляется с помощью процедуры TextOut.

Работа с динамической памятью требует контроля возникновения воз­можных исключительных ситуаций. В программе это осуществляется с по­мощью двух вложенных операторов try...f inally...end. Как правило, объек­ты, которые автоматически создаются средой Delphi, автоматически и унич­тожаются. В данном примере мы создали свой объект canvas и поэтому должны сами его уничтожить. Первая конструкция try...finally отслежи­вает создание объекта Canvas, а вторая отслеживает подключение canvas к TTabCantrol. Соответственно после ключевых слов Finally высвобожда­ется занятая функцией GetDC и канвой память.

Рассмотрим, почему использовалась операция as. Sender - это пара­метр, с помощью которого в обработчик событий передается конкретный экземпляр объекта. Операция as - это подсказка компилятору, какого типа передаваемый объект. В данном случае это объект типа TTabControl.

ВАРИАНТНЫЙ ТИП ДАННЫХ

Этот тип данных объявляется с помощью ключевого слова Variant. Данные типа Variant представляют собой такие величины, тип которых либо неизвестен к началу работы программы, либо может изменяться в процессе ее выполнения. Они являются довольно гибким средством, но требуют до­полнительной памяти и работа с ними происходит медленнее, чем с другими типами. Поэтому использовать их следует только там, где это необходимо, например, при работе с OLE-объектами, программировании серверов и т.д.

Одна переменная вариантного типа может принимать значения различ- типов, например объявлено: var V: variant; D: Double; S:


 



 



string; W: Word;. Можно записать: D:= 6.88; V:= D; w: = V:= W; S:='BM РХТУ'; V:= S;.

Вариантный тип данных представляет собой запись и определен в моду ле System стандартным типом TVarData:

TvarData = record Vtype:word; Reservedl, Reserved2, Case Integer of

VarSmallint: (VSmallint:Smallint);

Varlnteger: {VInteger: Integer);

VarSingle: (VSingle: Single);

VarDouble: (VDouble: Double):

VarCurrency: (VCurrency: Currency)

VarDate: (VDate:Double);

VarOleStr: (VOleStr:PWideChar);

VarDispath: (VDispath:Pointer);

VarError: (VError:Integer);

VarBoolean: (VBoolean:WordBool);

VarUnknown: (VUnknown:Pointer);

VarByte: (VByte:Byte);

VarString: (VString:Pointer);

VarAny: (VAny:Pointer);

VarArray: (VArray:PVarArray);

VarByRef: (VPointer:Pointer); End;.

 
Reserved3:word;
 
 
 
 

 

Этот тип представляет собой запись с вариантной частью. Поле VType определяет конкретный текущий тип записываемого значения. Само значе­ние записывается в вариантной части записи. Три поля Reserved-l-2-З не используются. Case-константы, определяющие вариантную часть, описаны в модуле System.

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

Какие-либо параметры вариантного типа могут быть определенного ти­па, неназначенные и неизвестные. Неназначенный параметр - это параметр, которому не назначено еще никакого значения. При своем создании пара­метр вариантного типа объявляется как неназначенный и получает значение varEmpty, где varEmpty - константа, определенная в модуле System. Неиз­вестные параметры, как правило, являются ошибочными параметрами.

В общем случае, переменные вариантного типа могут участвовать в вы­ражениях, как и переменные других типов. Этот тип данных может пред­ставлять собой массив, в том числе массив, состоящий из элементов вари­антного типа. Дня работы с такими массивами имеются стандартные под­программы.


 

ПРОЦЕДУРЫ И ФУНКЦИИ

Обычно программа составляется так, что она состоит из блоков, которые строятся в какой-то степени произвольно. К крупным блокам относятся мо­дули (Unit), библиотеки (DLL). К мелким блокам относятся подпрограммы, которые являются составной частью любых программных единиц. Подпро­грамма выполняет некоторую логически завершенную последовательность действий.

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

Существуют предопределенные встроенные подпрограммы, которые со­держатся в программных модулях и библиотеках. Подпрограммы может соз­давать и сам программист.

При разработке подпрограммы важным является вопрос категорий ис­пользуемых аргументов. Дело в том, что внутри подпрограммы все данные и вычисления локализованы, т.е. они недоступны (если не позаботиться об этом) для основной программы. Обмен результатами расчетов осуществля­ется с помощью параметров (аргументов). Существует два вида параметров: входные параметры, с помощью которых данные передаются внутрь подпро­граммы, и выходные, с помощью которых передаются результаты расчета. Обмениваться данными с подпрограммой можно с помощью глобальных переменных (не рекомендуется). В этой связи различают:

локальные переменные, объявленные внутри подпрограммы и доступ­
ные только ей;

глобальные переменные, объявленные в блоках, к которым принадле­
жит данная подпрограмма, и доступные как охватывающему подрограмму
блоку, так и подпрограмме;

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

Способ обмена данными с помощью глобальных переменных применя­ется только в простейших программах или каких-то блоках. Универсальным способом обмена данными является способ использования формальных па­раметров, который и разработан для этих целей.


ПРОЦЕДУРА

Заголовок процедуры имеет следующий синтаксис: Procedure <имя>(<список формальных парам.>);.Например, пусть заданы 2 мас­сива вещественных чисел, преобразовать их в массивы целых чисел.

Program primer;

Type Arlnt = Array[1..100] of Integer;

ArFloat = Array[1..100] of Double;

var Arlntl, Arlnt2:Arlnt;

ArFloatl, ArFloat2: ArFloat;

procedure Floattolnt (n:byte; const IntArray: Arlnt; var FloatArray: ArFloat);

var i: Byte; Begin

for i:=l to n do IntArray[i]:=round(FloatArray[i]); End; begin

FloatToInt (20, Arlntl, ArFloatl);

FloatToInt {30, Arlnt2, ArFloat2); End.

При разработке подпрограммы следует выделять входные и выходные параметры. В данном случае подпрограмма имеет два входных параметра: п и IntArray - и один выходной - FloatArray. В то же время эти параметры являются формальными параметрами. Фактические параметры - это "на­стоящие" переменные, с помощью которых заменяются формальные пара­метры при выполнении расчетов, т.е. при вызове процедуры (в примере имеются два вызова процедуры между begin и end).

ФУНКЦИЯ

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

Заголовок функции имеет следующий синтаксис: Function <имя> (<список формальных парам.>): <тип возвращаемого результа-та>;.

Как следует из объявления, необходимо задавать тип возвращаемого ре­зультата. Это означает, что имя функции представляет собой ячейку (сово­купность ячеек) памяти, с помощью которой результат расчета передается в блок, который является владельцем данной функции. Таким образом, син­таксис функции не указывает на то, что передавать данные нужно с помо-


щью выходных формальных параметров, как для процедуры. Например, рас­смотрим вычисление факториала N! =N(N-1).... Напишем функцию для вычисления:

■ Function Factorial(N:Byte): Cardinal;

Var Fact: Cardinal; i: Byte; begin

If N=0 then Fact:=l else Fact:= N;

For i:= N-l downto 2 do Fact:= Fact * i;

Factorial:= Fact; End;.

Здесь введена вспомогательная переменная Fact. Необходимость этого заключается в следующем. Дело в том, что, если справа от знака присваива­ния появляется ИМЯ функции, например, Factorial: = i*Factorial;, TO это означает, что справа при расчете функция вызывает саму себя (рекур­сия). Рекурсия - особая форма математических вычислений, когда функция строится посредством рекурентных соотношений, вызывая саму себя. В дан­ном примере не используется рекурсивная форма расчета факториала, по­этому необходимо написать все операторы без вызова самой функции Fac­torial. Для того чтобы упростить программирование функций и не вводить вспомогательных переменных типа Fact, синтаксически встроена специаль­ная переменная Result, которая имеет тот же тип, что и функция, и исполь­зуется только внутри функций. Перепишем подпрограмму, приведенную выше:

Function Factorial (N: Byte): Cardinal;

Var I: Byte; begin

If N=0 then Result:= 1 else Result:= N;

For i:= N-l downto 2 do Result:= Result * i; End;.

В данном случае использование справа от знака присваивания перемен­ной Result рекурсии не образует. Присваивание результата расчета имени функции из переменной Result осуществляется автоматически.

Для расчета, например 12!, сначала объявим какую-либо переменную (пусть Q) var q: Cardinal;. Теперь можно записать оператор вычисле­ния 12! Q:= Factorial {12);.

Подпрограмму-функцию при необходимости можно вызвать так же, как процедуру, если программиста не интересует результат, возвращаемый Функцией, а важны те действия, которые она выполняет. Такая возможность задается с помощью директивы {SX+} (расширенный синтаксис, установле­но по умолчанию).


 




 

 



Поделиться с друзьями:


Дата добавления: 2014-12-29; Просмотров: 400; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.011 сек.