КАТЕГОРИИ: Архитектура-(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;.
Этот тип представляет собой запись с вариантной частью. Поле 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 это означает, что справа при расчете функция вызывает саму себя (рекурсия). Рекурсия - особая форма математических вычислений, когда функция строится посредством рекурентных соотношений, вызывая саму себя. В данном примере не используется рекурсивная форма расчета факториала, поэтому необходимо написать все операторы без вызова самой функции Factorial. Для того чтобы упростить программирование функций и не вводить вспомогательных переменных типа 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; Просмотров: 416; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |