Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
методички по информатике / Конспект лекций (Delphi).pdf
Скачиваний:
63
Добавлен:
27.05.2015
Размер:
1.2 Mб
Скачать

21

Пример 2 (обработка файла с множествами):

procedure TForm1.Button1Click(Sender: TObject); var

fIn,fOut : TextFile;

Processing : set of (DelEndSpace, DelSomeSpace, DelEmptyLine); s : string;

i : integer; begin

Processing := [];

if EndSpaceCB.Checked then

Processing := Processing+[DelEndSpace]; if TwoSpaceCB.Checked then

Processing := Processing+[DelSomeSpace]; if EmptyLineCB.Checked then

Processing := Processing+[DelEmptyLine]; AssignFile(fIn,???);

Reset(fIn);

AssignFile(fOut,???);

Rewrite(fOut);

while not Eof(fIn) do begin

readln(fIn,s);

if DelEndSpace in Processing then s := Trim(s);

if DelSomeSpace in Processing then while Pos(' ',s)>0 do

Delete(s, Pos(' ',s,1); if (s<>'') or ((s='') and

(not(DelEmptyLine in Processing))) then writeln(fOut,s);

end;

CloseFile(fIn);

CloseFile(fOut);

end;

1.15 Перечисляемый тип

В разделе пользовательских типов тип Month описывает так называемый перечисляемый тип, формат которого

<идентификатор> = (<элемент1> [,<элемент2> …])

Перечисляемый тип задает множество значений, которые может принимать переменная. Его применение позволяет избежать ошибок выхода переменной за заданные границы и улучшает читабельность программы.

Каждому элементу перечисляемого типа соответствует числовое значение: первому элементу – 0, второму – 1 и т.д.

Пример (определение числа дней в месяцах года):

22

procedure TForm1.Button1Click(Sender: TObject); type

Months = (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec); const

DayOfMonth : array[Months] of integer = (31,28,31,30,31,30,31,31,30,31,30,31);

NameMonths : array[Months] of string = ('январь','февраль','март','апрель','май','июнь',

'июль','август','сентябрь','октябрь','ноябрь','декабрь');

var

Year,n : integer; i : Months;

begin

Year := ???;

for i := Jan to Dec do begin

n := DayOfMonth[i]; if i=Feb then

if ((Year mod 4=0) and (Year mod 100<>0)) or (Year mod 400=0) then

n := 29;

<вывод NameMonths[i]+' - '+IntToStr(n)>; end;

end;

1.16 Тип-диапазон

Тип диапазон схож с перечисляемым типом, но набор возможных значений задается как диапазон некоторого порядкового типа:

<идентификатор> = <начало> .. <окончание>,

например

type

Less10 = 1..9; Letter = 'a'..'z';

Как и перечисляемый тип, тип диапазон позволяет избегать выхода значения переменной за границы заданного диапазона.

Для определения минимального и максимального индексов типадиапазона можно воспользоваться функциями Low(X) и High(X), где X – переменная или сам тип.

Пример (определение количества дней в квартале не високосного года):

procedure TForm1.Button1Click(Sender: TObject); type

Months = (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec); First = Jan..Mar;

23

Second = Apr..Jun;

Third = Jul..Sep;

Fourth = Oct..Dec;

NumQuarter = 1..4; const

DayOfMonth : array[Months] of integer = (31,28,31,30,31,30,31,31,30,31,30,31);

var

i : Months;

Quarter : NumQuarter; Sum : integer;

begin

Quarter := ???;

Sum := 0;

case Quarter of

1 : for i := Low(First) to High(First) do Sum := Sum+DayOfMonth[i];

2 : for i := Low(Second) to High(Second) do Sum := Sum+DayOfMonth[i];

3 : for i := Low(Third) to High(Third) do Sum := Sum+DayOfMonth[i];

4 : for i := Low(Fourth) to High(Fourth) do Sum := Sum+DayOfMonth[i];

end;

<вывод Sum>; end;

1.17 Функции и процедуры

Процедуры и функции представляют собой относительно самостоятельные фрагменты программы, оформленные особым образом и имеющие идентификатор. Чаще всего они используются для описания повторяющегося фрагмента программы. Отличие функции от процедуры заключается в том, что результатом выполнения функции всегда является некоторое значение, которое может быть использовано в дальнейшем в выражении.

В дальнейшем будем называть процедуры и функции подпрограммами, если не требуется уточнение. Формат описания заголовка:

procedure <идентификатор>[(<список формальных параметров>)];

function <идентификатор>[(<список формальных параметров>)] : <возвращаемый тип>;

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

24

Для вызова подпрограммы из основной программы требуется ввести ее идентификатор и указать фактические параметры, причем их количество и тип должны в точности соответствовать <списку формальных параметров>.

При описании <списка формальных параметров> каждый из параметров может быть одного из трех типов:

параметр-переменная. Перед описанием такого параметра следует указывать ключевое слова var. Такой параметр напрямую передаются в подпрограмму, и его изменение в теле подпрограммы приводит к изменению фактического параметра, т.е. параметр-переменную можно использовать для возврата в основную программу видоизмененного значения. Параметр-переменная не может быть константой или результатом вычисления выражения;

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

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

Так как подпрограммы являются относительно независимыми фрагмен-

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

begin … end;.

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

При описании тела функции следует указать, какое значение функция будет возвращать. Это делается путем присвоения идентификатору функции требуемого значения.

При использовании в качестве параметра подпрограммы массива, следует применять предварительное описание пользовательского типа, например:

type

Mas = array[1..100] of integer; procedure First(var A : Mas);

Запись procedure First(var A : array[1..100] of integer); не-

допустима.

25

Однако допустима запись procedure First(var A : array of inte-

ger);, в которой происходит использование так называемых открытых массивов, позволяющее передавать подпрограмме массивы переменной длины. Такой массив трактуется подпрограммой как одномерный массив с начальным индексом 0. Конечный индекс может быть определен с помощью функции High() (например, High(A)).

В большинстве случаев при передаче в подпрограмму в качестве параметра массива, требуется и передача фактического числа элементов массива, так как максимальное и текущее количество элементов массива часто различны.

Если в теле подпрограммы требуется использование дополнительных переменных, то в большинстве случаев целесообразно описание данных переменных именно внутри подпрограммы.

Пример (определение суммы элементов и среднего из положительных элементов для каждого из двух одномерных массивов):

procedure TForm1.Button1Click(Sender: TObject); type

Mas = array[1..100] of integer; var

Mas1,Mas2 : Mas; Count1,Count2,Sum,i : integer; Average : real;

function Summa(A : Mas; Count : integer) : integer; var

i,Sum : integer; begin

Sum := 0;

for i := 1 to Count do Sum := Sum+A[i];

Result := Sum; end;

function AveragePositive(A : Mas; Count : integer;

var Average : real) : boolean;

var

i,CountPositive : integer;

Temp : real; // Объяснить, зачем нужна begin

CountPositive := 0; Temp := 0;

for i := 1 to Count do if A[i]>=0 then begin

inc(CountPositive); Temp := Temp+A[i];

end;

if CountPositive>0 then begin