Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Расписанные билеты (Pascal).doc
Скачиваний:
1
Добавлен:
01.05.2025
Размер:
676.86 Кб
Скачать

Типизированные файлы

Типизированный файл – это файл, в котором содержатся однотипные данные. Типизированный файл задается с помощью 2-х ключевых слов «file of». После слова «of» указывается тип файла, например integer, real, char, string и т.д. Тип файла может быть любым за исключением файлового типа (не может быть файла файлов) и комбинированного типа, один из компонентов которого имеет файловый тип.

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

<Объявление файловой переменной для типизированного файла> ::=

var

<Имя переменной>: file of <тип>;

Процедуры и функции для работы с типизированными файлами (TP7)

procedure Assign(var F: File);

procedure Close (var F: File);

procedure Reset (var F: File);

Открывает существующий файл на чтение и запись. Маркер файла становится перед записью номер 0. Нумерация компонент начинается с нуля.

procedure Rewrite (var F: File);

Открывает файл на чтение и запись. Маркер файла становится перед записью номер 0. Файл после открытия имеет размер 0. Если файл ранее существовал, его содержимое теряется.

procedure Seek(var F: File, RecordNumber: Longint);

Перемещает маркер файла на компонент с номером RecordNumber. Нумерация компонент начинается с нуля.

procedure Truncate(var F: File);

Удаляет все компоненты файла, стоящие после маркера файла.

procedure Read(var F: File; <Список ввода>);

Читает из файла N компонент, где N – число пунктов в <Списке ввода>. Маркер файла перемещается вперед на N компонент.

procedure Write(var F: File; <Список вывода>);

Зписывает в файл N компонент, где N – число пунктов в <Списке ввода>. Маркер файла перемещается вперед на N компонент.

function Eof(var F: File): boolean;

Синтаксис Delphi:

procedure AssignFile(var F: <Файловый тип>; <Имя файла>: string);

procedure CloseFile (var F: <Файловый тип>);

Билет №24

Тип «Указатель»

<Тип «Указатель»> : : =

^<Тип> ;

<Тип «Указатель»> : : =

pointer ;

Тип «Указатель» используется для объявления переменной, которая должна содержать адрес некоторого набора данных в оперативной памяти. Таким адресом может быть либо адрес первого байта уже существующей переменной, либо адрес первого байта нового набора данных, создаваемого специально для этого предназначенной процедурой.

Существует специальное значение для указателя, имеющее имя Nil. Если указатель равен Nil, это означает, что он ни на что не указывает. Если указатель не инициализирован, нет гарантии, что он равен именно Nil.

Пример.

program P0801;

type

pInteger = ^integer ;

ppInteger = ^pInteger ;

pppInteger = ^ppInteger ;

var

p_i: ^integer ; // Аналогично p_i: pInteger ;

p_b: ^boolean ;

p_c: ^char ;

p: pointer ;

c: char ;

b: boolean ;

i: integer ;

begin

Writeln('sizeof(p)=', sizeof(p)) ;

Writeln('sizeof(b)=', sizeof(b)) ;

Writeln('sizeof(i)=', sizeof(i)) ;

Writeln('sizeof(c)=', sizeof(c)) ;

Readln;

b:=false ;

Writeln(b) ;

p_b := @b ; // p_i := @b ;

p := p_b ;

p_i := p ;

p_i^ := 7 ;

Writeln(b) ;

c:='A' ;

Writeln(c) ; { 'A' }

p_c := @c ;

p := p_c ;

p_i := p ;

p_i^ := p_i^ + 7 ;

Writeln(c) ; { 'H' }

Readln ;

end.

Билет №25

Тип pChar

Фактически:

type

pChar = ^Char;

Тип pChar предназначен для работы со строковыми данными в формате “Zero Terminated Strings” («Строки с нулевой концовкой»). Указатель типа pChar содержит адрес «первого» байта (символа) строки. Правда, нумерацию символов принято начинать не с единицы, а с нуля. Признаком конца строки служит символ с кодом 0 (#0). Последним символом строки будет тот, сразу после которого расположен символ #0.

Строки “Zero Terminated Strings” имеют и другое название:

ASCIIZ–строки.

Пример

var

mC: array[0..11] of char;

begin

mC[0] := ‘N’; mC[1] := ‘o’; mC[2] := ‘v’; mC[3] := ‘e’; mC[4] := ‘m’;

mC[5] := ‘b’; mC[6] := ‘e’; mC[7] := ‘r’;

mC[8] := #0; // mC[8] := Chr(0);

StrPCopy(mC, ‘November’);

end.

Процедура StrDispose

procedure StrDispose(SP: PChar);

Удаляет из динамической памяти строку. Строка размещается в динамической памяти функцией StrNew.

SP – удаляемая строка.

Если SP = nil, процедура ничего не выполняет.

Функция StrCat

function StrCat(Dest, Source: PChar): PChar;

Присоединяет к концу строки Dest строку Source. Результат – объединенная строка. Размер полученной строки не контролируется. Dest – первая строка; Source – вторая строка.

Функция StrComp

function StrComp(SPl, SP2: PChar): Integer;

Сравнивает две строки (символы сравниваются слева направо своими кодами). Результат меньше нуля, если первая строка меньше второй, равен нулю, если строки равны, и больше нуля, если первая строка больше второй.

Функция StrCopy

function StrCopy(Dest, Source: PChar): PChar;

Копирует строку Source в строку Dest. Возвращает в качестве результата новую строку Dest.

Source – копируемая строка;

Dest – строка для копирования.

Размер полученной строки не контролируется.

Функция, StrECopy

function StrECopy(Dest, Source: PChar): PChar; Копирует строку Source в строку Dest. Возвращает в качестве результата указатель на последний (нулевой) элемент строки.

Source – копируемая строка;

Dest – строка для копирования.

Размер полученной строки не контролируется.

Функция StrEnd

function StrEnd(SP: PChar): PChar;

Получает указатель на конец строки SP (на завершающий нулевой элемент).

SP – исходная строка.

Функция StrlComp

function StrLComp(SPl, SP2: PChar): PChar;

Сравнивает строки SPl и SP2 без различия между прописными и строчными латинскими буквами. Результат такой же, что и у функции StrComp.

SPl, SP2 – сравниваемые строки.

Функция StrLCat

function StrLCat(Dest,Source: PChar; MaxLen: Word): PChar;

Добавляет в конец строки Dest MaxLen символов строки Source. Если размер

строки Source меньше MaxLen, копируется фактическое количество символов. В

качестве результата возвращает объединенную строку.

Dest – первая строка;

Source – копируемая строка;

MaxLen – число копируемых символов.

Размер полученной строки не контролируется.

Функция StrLComp

function StrLComp(SPl, SP2: PChar; MaxLen: Word): PChar;

Сравнивает MaxLen первых символов строк SPl и SP2. Если размер строк меньше MaxLen, сравнивается фактическое количество символов. Результат такой же, что и у функции StrComp.

SPl, SP2 – сравниваемые строки;

MaxLen – число сравниваемых символов.

Функция StrLCopy

function StrLCopy(Dest, Source; PChar; MaxLen: Word): PChar;

Копирует MaxLen символов строки Source в строку Desi. Если размер строки Source меньше MaxLen, копируется фактическое число символов. Результат – скопированная строка.

Dest – строка для копирования;

Source – колируемая строка;

MaxLen – число копируемых символов.

Размер полученной строки не контролируется.

Функция StrLen

function StrLen(SP: PChar): Word;

Определяет размер строки без учета заключительного символа с кодом 0.

SP – исследуемая строка.

Функция StrLIComp

function StrLIComp(SPl, SP2: PChar; MaxLen: Word): PChar;

Сравнивает MaxLen первых символов строк SPl и SP2 без различия между прописными и строчными латинскими буквами. Если размер строк меньше MaxLen, сравнивается фактическое число символов. Результат такой же, что и у функции StrComp.

SPl,SP2 – сравниваемые строки;

MaxLen – число сравниваемых символов.

Функция StrLower

function StrLower(SP: PChar): PChar;

Преобразует в строке SP прописные латинские буквы в строчные. Результат –преобразованная строка.

SP – преобразуемая строка.

Функция StrMove

function StrMove(Dest, Source: PChar; Count: Word): PChar;

Копирует Count символов строки Source в строку Dest, даже если это число больше размера строки Source. Результат – скопированная строка.

Dest – первая строка;

Source – вторая строка. Размер полученной строки не контролируется.

Функция StrNew

function StrNew(SP: PChar): PChar;

Создает в динамической области копию строки SP. Результат – указатель на новую строку. Удаляется строка процедурой StrDispose.

SP – копируемая строка.

Функция StrPas

function StrPas(SP: PChar): string;

Преобразует ASCIIZ–строку в строку типа string. Результат – преобразованная строка.

SP – исходная строка.

Функция StrPCopy

function StrPCopy(Dest: PChar; Source: string): PChar; Преобразует строку Source типа string в ASCHZ–строку Dest. Результат – указатель на преобразованную строку.

Source – преобразуемая строка;

Dest – преобразованная строка.

Размер полученной строки не контролируется.

Функция StrPos

function StrPos(SPl, SP2: PChar): PChar;

Ищет первое вхождение строки SP2 в строку SPl. Результат – указатель на первое вхождение строки SP2 в строку SPl – либо nil, если такого вхождения нет.

SPl – строка, в которой ищется вхождение строки SP2;

SP2 – искомая строка.

Функция StrRScan

function StrRScan(SP: PChar; Chr: Char): PChar;

Ищет последнее вхождение символа Chr в строку SP. Результат – указатель на найденный символ либо nil, если такого символа нет.

SP – строка, где ищется символ;

Chr – искомый символ.

Функция StrScan

function StrScan(SP: PChar; Chr: Char): PChar;

Ищет первое вхождение символа Chr в строку SP Результат – указатель на найденный символ либо nil, если такого символа нет.

SP – строка, где ищется символ;

Chr – искомый символ.

Функция StrUpper

function StrUpper(SP: PChar): PChar;

Преобразует в строке SP строчные латинские буквы в прописные. Результат – преобразованная строка.

SP – преобразуемая строка.

Билет №26

Ключи компиляции (директивы компилятора)

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

Ключ является глобальным, если в модуле он может присутствовать только в одном месте – в начале модуля. Режим, задаваемый глобальным ключом, действует на весь модуль.

Ключ является локальным, если в модуле он может присутствовать во многих местах. Режим, задаваемый локальным ключом, действует на тот участок кода, который предшествует прямо противоположному ключу.

Выравнивание полей записей и классов

{$A+}, {$A-}, {$A1}, {$A2}, {$A4}, or {$A8}

или

{$ALIGN ON}, {$ALIGN OFF}, {$ALIGN 1}, {$ALIGN 2}, {$ALIGN 4},

or {$ALIGN 8}

По умолчанию:

{$A8}

или

{$ALIGN 8}

Зона действия: Локальный

Полное вычисление логических выражений

{$B+} or {$B-}

или

{$BOOLEVAL ON} or {$BOOLEVAL OFF}

По умолчанию:

{$B-}

или

{$BOOLEVAL OFF}

Зона действия: Локальный

Пример

x := 3;

{$B-}

if

(x > 4) // Вычисляется

and

(x < 5) // НЕ вычисляется

then . . . ;

Использование длинных строк (AnsiString)

{$H+} or {$H-}

или

{$LONGSTRINGS ON} or {$LONGSTRINGS OFF}

По умолчанию:

{$H+}

или

{$LONGSTRINGS ON}

Зона действия: Локальный

Проверка результата ввода-вывода

{$I+} or {$I-}

или

{$IOCHECKS ON} or {$IOCHECKS OFF}

По умолчанию:

{$I+}

или {$IOCHECKS ON}

Зона действия: Локальный

Разрешение использовать типизированные константы как переменные

{$J+} or {$J-}

или

{$WRITEABLECONST ON} or {$WRITEABLECONST OFF}

По умолчанию:

{$J-}

или

{$WRITEABLECONST OFF}

Зона действия: Локальный

Генерация информации о текущих типах полей, методов, свойств, объявленных в секции Published (RTTI, RunTime Type Information)

{$M+} or {$M-}

или

{$TYPEINFO ON} or {$TYPEINFO OFF}

По умолчанию:

{$M-}

или

{$TYPEINFO OFF}

Зона действия: Локальный

Если класс объявлен в режиме {$M-}, или не является потомком класса, объявленного в режиме {$M+}, секция Published запрещена.

Задание размера стека

{$M <Число: Мин. размер стека>, < Число: Макс. размер стека>}

или

{$MINSTACKSIZE <Число>}

{$MAXSTACKSIZE <Число>}

По умолчанию:

{$M 16384, 1048576}

Зона действия: Глобальный

1024 ≤ <Число: Мин. размер стека> ≤ 2147483647

<Число: Мин. размер стека> ≤ <Число: Макс. размер стека> ≤ 2147483647

Проверка выхода за пределы диапазона

{$R+} or {$R-}

или

{$RANGECHECKS ON} or {$RANGECHECKS OFF}

По умолчанию:

{$R-}

или

{$RANGECHECKS OFF}

Зона действия: Локальный

Пример. TP7

var

i: integer;

mA, nB: array[1..10] of integer;

begin

for i := 1 to 10 do begin mA[i] := 0; mB[i] := 0; end;

{$R-}

i := 12;

mA[i] := -7;

writeln(mA[i]); // -7

writeln(mB[2]); // -7

{$R+}

mA[i] := -7; // RunTime Error

writeln(mA[12]); // Constant Out Of Range

end.

Проверка переполнения при арифметических операциях

{$Q+} or {$Q-}

или

{$OVERFLOWCHECKS ON} or {$OVERFLOWCHECKS OFF}

По умолчанию:

{$Q-}

или

{$OVERFLOWCHECKS OFF}

Зона действия: Локальный

Пример. TP7

var

L: integer;

begin

L := 2000000000;

{$Q-}

L := L*L; // Реакции на переполнение нет

writeln(L); // -1651507200

L := 1000000000;

{$Q+}

L := L*L; // RunTime Error

end.

Разрешение использовать расширенный синтаксис

{$X+} or {$X-}

или

{$EXTENDEDSYNTAX ON} or {$EXTENDEDSYNTAX OFF}

По умолчанию:

{$X+}

или

{$EXTENDEDSYNTAX ON}

Зона действия: Глобальный

Пример 1. TP7

{$X+}

var

p: pChar; // То же, что p = ^Char;

const

mC: array[0..39] of char = 'Petrov'#0; // Синтаксическая ошибка при {$X-}

begin

// Во ВСЕХ последующих операторах

// будет выявлена синтаксическая ошибка при ключе {$X-}

// При ключе {$X+} код нормально компилируется и работает.

p := 'Nikolaev';

writeln(Ord(p[8])); // 0

writeln(p);

p := @mC;

writeln(p);

writeln(p[0]);

end.

Пример 2. TP7

{$X+}

uses crt;

var

c: char;

x, y: double;

begin

c := readkey;

ReadKey; // Синтаксическая ошибка при {$X-}

x := pi/2; y := sin(x);

sin(x); // Синтаксическая ошибка в любом случае

end.

Пример 3. Delphi

{$X+}

function Factorial(N: longint): longint;

var i: longint;

begin

Result := 1; // Синтаксическая ошибка при {$X-}

for i := 2 to N do Result := Result * i; // Синтаксическая ошибка при {$X-}

end;

Условная компиляция

{$define <Имя режима>} // Режим “<Имя режима>” включен

{$undef <Имя режима>} // Режим “<Имя режима>” выключен

{$ifdef <Имя режима>}

<Фрагмент кода 1>

// Выполняется только если режим “<Имя режима>” включен

{$else}

<Фрагмент кода 2>

// Выполняется только если режим “<Имя режима>” выключен

{$endif}

{$ifndef <Имя режима>}

<Фрагмент кода 2>

// Выполняется только если режим “<Имя режима>” выключен

{$else}

<Фрагмент кода 1>

// Выполняется только если режим “<Имя режима>” включен

{$endif}

Билет №27

Объектно-ориентированное программирование (ООП)

Понятие класса – дополнение к понятию типа.

Тип [обычной] переменной определяет множество значений, которые она способна принимать, и множество операций, которые над ней можно производить.

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

Три принципа ООП:

Инкапсуляция

Наследование

Полиморфизм

Инкапсуляция – соединение в единой структуре данных и программных кодов (т.н. методов), предназначенных для обработки именно этих данных.

Наследование – возможность построения нового класса на основе существующего (т.н. базового, или родительского) класса с дополнением и/или переопределением данных и методов. Наследование есть механизм передачи данных и методов родительского класса в дочерний класс.

Полиморфизм – возможность обращения по одному имени к разным методам.

Объектом, или объектной переменной принято называть конкретный экземпляр переменной заданного класса.

По сути (но не по синтаксису), объектная переменная есть указатель на первый байт области памяти, выделенной под поля объекта. Эта область памяти предоставляется объекту тогда, когда он «начинает жить», и высвобождается тогда, когда он свою жизнь завершает.

Вместе с «рождением» первого экземпляра объекта заданного класса в память загружается и его инкапсулированные программные коды. Второй и последующие экземпляры, занимая под свои поля новые области памяти, пользуются уже загруженным кодом первого экземпляра.

Три группы атрибутов объекта:

Методы

Свойства

События

Методы – процедуры и функции, описываемые при описании класса, предназначенные для приема объектом данных извне, изменения данных внутри объекта (модификации полей), подачи данных от объекта внешним «потребителям».

Свойства (для пользователя объекта) – параметры (числовые, символьные, строковые и прочих типов), характеризующие состояние объекта в данный момент. Обращение к свойствам объекта внешне выглядит как обращение к полям переменной типа «запись».

Свойства (для программиста класса) – процедуры и функции, назначение которых совпадает с назначением методов. В среде программистов не утихают споры о праве свойств на существование.

События – это то, что с объектом «может произойти», и на что можно предусмотреть реакцию кода класса.

Объявление класса

<Имя класса> = class(<Имя базового класса>)

private

<Объявление закрытых полей и методов>

// Все, что объявлено здесь, может быть использовано только в данном модуле

protected

<Объявление открытых полей и методов>

// Все, что объявлено здесь, может быть использовано

// и в данном модуле, и во всех классах-наследниках данного класса

public

<Объявление открытых полей и методов>

// Все, что объявлено здесь, может быть использовано везде, где виден класс

published

<Объявление открытых полей и методов>

// видно в Инспекторе объектов

end;

Всё, что объявлено в разделе published, может быть использовано везде, где виден класс.

Раздел published может присутствовать, только если включен режим «динамическая идентификация типа данных» (Run-time type information, Run-time type identification, RTTI), который позволяет определить тип данных переменной или объекта во время выполнения программы.

Режим RTTI должен быть включен с помощью ключа {$M+}.

Билет №28

Конструктор

Объявление:

constructor TList1.Create;

begin

inherited Create;

// inherited;

pHead := Nil;

pTail := Nil;

nItems := 0;

end;

Обращение:

MyList1 := TList1.Create;

Обращение происходит к методу класса.

Деструктор

Объявление:

destructor TList1.Destroy;

begin

inherited Destroy;

// inherited;

end;

Обращение:

MyList1.Destroy;

Обращение происходит к методу объекта.

Дополнительно о полиморфизме

Как уже говорилось, каждый класс может иметь несколько конструкторов и

несколько деструкторов. Правила языка Delphi этого не запрещают. Однако, сре-

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

зовать несколько конструкторов и деструкторов.

Ниже приводится фрагмент текста для модуля Unit1.pas, в котором преду-

смотрено два деструктора.

В разделе интерфейса имеется два заголовка процедуры destructor. Наличие

двух заголовков сопровождается словами «overload» после них.

destructor Destroy; overload;

destructor Destroy(sFileName: string); overload;

Списки формальных параметров у заголовков должны быть такими, чтобы

не было «двусмысленности», т.е. чтобы компилятор мог однозначно определить

по списку фактических параметров, какой из двух разных кодов для процедуры с

одним именем следует применить.

Билет №29

Граф. Основные понятия и определения

Граф, или неориентированный граф – это упорядоченная пара , для которой выполнены следующие условия:

– это непустое множество вершин, или узлов,

– это множество пар (в случае неориентированного графа – неупорядоченных) вершин, называемых рёбрами.

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

Вершины и рёбра графа называются также элементами графа, число вершин в графе – порядком, число рёбер – размером графа.

Вершины и называются концевыми вершинами (или просто концами) ребра . Ребро, в свою очередь, соединяет эти вершины. Две концевые вершины одного и того же ребра называются соседними.

Два ребра называются смежными, если они имеют общую концевую вершину.

Два ребра называются кратными, если множества их концевых вершин совпадают.

Ребро называется петлёй, если его концы совпадают, то есть .

Степенью вершины называют количество инцидентных ей рёбер(при этом петли считают дважды).

Вершина называется изолированной, если она не является концом ни для одного ребра; висячей (или листом), если она является концом ровно одного ребра.

Ориентированный граф

Ориентированный граф (сокращённо орграф) – это упорядоченная пара , для которой выполнены следующие условия:

– это непустое множество вершин или узлов,

– это множество (упорядоченных) пар различных вершин, называемых дугами или ориентированными рёбрами.

Дуга – это упорядоченная пара вершин , где вершину называют началом, а – концом дуги. Можно сказать, что дуга ведёт от вершины к вершине .

Билет №30 - 32

Динамические структуры данных

Линейный однонаправленный список

procedure AppendItem(sName: string; Salary: double);

procedure InsertItem(sName: string; Salary: double);

{$F+}

{$N+}

uses Crt, Strings;

type

pPersonType = ^PersonType;

PersonType = record

sName: string[40];

Salary: double;

pNext: pPersonType;

end;

var

pHead, pTail, pCurr: pPersonType;

function CompareItems(pCurr1,pCurr2: pPersonType): integer;

var

. . .

begin

. . .

end;

function AloneItem(sName: string; Salary: double;

var pNew: pPersonType): boolean;

begin

New(pNew);

if pNew = Nil then Halt;

pNew^.sName := sName;

pNew^.Salary := Salary;

pNew^.pNext := Nil;

if pHead=Nil then

begin

pHead := pNew; pTail := pNew; AloneItem := true;

end

else

AloneItem := false;

end;

procedure AppendItem(sName: string; Salary: double);

var

pNew: pPersonType;

begin

if not AloneItem(sName, Salary, pNew) then

begin

pTail^.pNext := pNew;

pTail := pNew;

end;

end;

procedure PrependItem(sName: string; Salary: double);

var

pNew: pPersonType;

begin

if not AloneItem(sName, Salary, pNew) then

begin

pNew^.pNext := pHead;

pHead := pNew;

end;

end;

Билет №33

Параметры без типа

{$X+}

{$N+} (* Только для TP7 *)

program Project2;

var

i: integer;

d: double;

s: string[2];

procedure ShowInteger(var x);

begin

writeln(Integer(x));

end;

procedure ShowDouble(var x);

begin

writeln(Double(x));

end;

procedure ShowString(var x);

begin

writeln(String(x));

end;

Билет №34

Процедурные типы

<Объявление типа «Процедура» > :: =

<Имя Типа> = procedure(<Список формальных параметров>) ;

<Объявление типа «Функция» > :: =

<Имя Типа> = function(<Список формальных параметров>): <Тип> ;

После объявления процедурного (или «функционального») типа можно объявлять переменные такого типа. Этим переменным можно будет присваивать «имена» уже описанных процедур или функций, а затем обращаться к ним по имени процедурной переменной.

На деле переменные процедурных типов являются указателями. До инициализации они имеют непредсказуемое значение. Не следует надеяться, что это именно Nil. Ответственность за вызов процедуры, на которую «указывает» неинициализированная процедурная переменная, несёт программист.

Билет №35

Оператор выбора

< Оператор выбора> ::=

case <Выражение-селектор> of

<Список 1> :

<Оператор 1> ;

<Список 2> :

<Оператор 2> ;

. . .

<Список N> :

<Оператор N> ;

else

<Операторы> ;

End

Записи с вариантной частью

type

MyTagType0 = (Type00, Type01, Type02, Type03);

MyTagType01 = (Type010, Type011, Type012, Type013);

MyTagType02 = (Type020, Type021, Type022, Type023);

MyRecordType1 = record

i: integer; d: double;

case Tag0: MyTagType0 of

Type00:

(

s: string[7];

mA: array[1..3] of single;

);

Type01:

(

R1, R2: MyRecordType2D;

);

Type02 .. Type03:

(

c1: char;

T1: TDateTime;

);

end;

MyRecordType2 = record

r: single;

case Tag0: MyTagType0 of

Type00:

(

bWas: boolean; mC: array[1..4] of char;

case Tag01: MyTagType01 of

Type010: (k: integer;);

Type011 .. Type013: (b: byte;);

);

Type01:

(

R1, R2: MyRecordType2D;

case Tag02: MyTagType02 of

Type020: (c: char;);

Type021 .. Type023: (s0: shortint;);

);

end;

Билет №36

Типизированные файлы

<Объявление файловой переменной для типизированного файла> ::=

var

<Имя переменной>: file of <тип>;

Процедуры и функции для работы с типизированными файлами (TP7)

procedure Assign(var F: File);

procedure Close (var F: File);

procedure Reset (var F: File);

Открывает существующий файл на чтение и запись. Маркер файла становится перед записью номер 0. Нумерация компонент начинается с нуля.

procedure Rewrite (var F: File);

Открывает файл на чтение и запись. Маркер файла становится перед записью номер 0. Файл после открытия имеет размер 0. Если файл ранее существовал, его содержимое теряется.

procedure Seek(var F: File, RecordNumber: Longint);

Перемещает маркер файла на компонент с номером RecordNumber. Нумерация компонент начинается с нуля.

procedure Truncate(var F: File);

Удаляет все компоненты файла, стоящие после маркера файла.

procedure Read(var F: File; <Список ввода>);

Читает из файла N компонент, где N – число пунктов в <Списке ввода>. Маркер файла перемещается вперед на N компонент.

procedure Write(var F: File; <Список вывода>);

Зписывает в файл N компонент, где N – число пунктов в <Списке ввода>. Маркер файла перемещается вперед на N компонент.

function Eof(var F: File): boolean;

Синтаксис Delphi:

procedure AssignFile(var F: <Файловый тип>; <Имя файла>: string);

procedure CloseFile (var F: <Файловый тип>);

Процедуры аналогичны соответственно процедурам Assign и Close.

Билет №37

Свойство (Property)

Свойство, как и поле класса, задает атрибут объекта. Но если поле есть просто хранилище данных, то свойство есть механизм обращения к данным и, возможно, механизм изменения данных. Свойство ограничивает доступ к данным теми рамками, которые задает программист.

Объявление:

public

property <Имя свойства>: <Тип>

read <Имя функции или поля для чтения> // Может отсутствовать, если есть write

write <Имя процедуры для модификации> // Может отсутствовать, если есть read

;

Пример. Delphi

TList1 = class(TObject)

private

pHead: pPersonType;

nItems: integer;

procedure DeleteTail(pFirstInTail: pPersonType);

public

function ItemsCountR: integer;

procedure ItemsCountW(k: integer);

property ItemsCount: integer read ItemsCountR write ItemsCountW;

end;

procedure TList1.DeleteTail(pFirstInTail: pPersonType);

var

pCurr, pDelete: pPersonType;

begin

pCurr := pFirstInTail;

while pCurr <> Nil do

begin

pDelete := pCurr;

pCurr := pCurr^.pNext;

Dispose(pDelete);

end;

end;

function TList1.ItemsCountR: integer;

var

pCurr: pPersonType;

n: integer;

begin

// ItemsCountR := nItems;

pCurr := pHead;

n := 0;

while pCurr <> Nil do

begin

Inc(n);

pCurr := pCurr^.pNext;

end;

nItems := n;

ItemsCountR := n;

end;

procedure TList1.ItemsCountW(k: integer);

var

pCurr, pPrev: pPersonType;

n: integer;

begin

// nItems := k;

if k < 0 then

begin

writeln(‘k must be non-negative!’);

Exit;

end;

pCurr := pHead;

n := 0;

while (pCurr <> Nil) and (n < k) do

begin

Inc(n);

pPrev := pCurr;

pCurr := pCurr^.pNext;

end;

if n < k then

begin

writeln(‘k must be less or equal to ’, n:0, ‘ !’);

Exit;

end;

pPrev^.pNext := Nil;

if pCurr <> Nil then

DeleteTail(pCurr);

nItems := k;

end;

Обращение к свойствам объекта:

Writeln(<Имя объектной переменной>.ItemsCount);

// Обращение к свойству “read”.

<Имя объектной переменной>.ItemsCount := 7;

// Обращение к свойству “write”.

Пример

var

MyList: TList1;

writeln(MyList1.ItemsCount);

writeln(MyList1.ItemsCountR);

MyList1.ItemsCount := 10;

MyList1.ItemsCountW(10);

Билет №38

Алгоритм Дейкстры (Dijkstra’s algorithm) – алгоритм на графах, изобретённый нидерландским ученым Э. Дейкстрой в 1959 году. Находит кратчайшее расстояние от одной из вершин графа до всех остальных. Алгоритм работает только для графов без рёбер отрицательного веса. Алгоритм широко применяется в программировании и технологиях, например, его использует протокол OSPF для устранения кольцевых маршрутов.

Дан взвешенный ориентированный граф без петель и дуг отрицательного веса.  – множество вершин, – множество рёбер графа.

Требуется найти кратчайшие пути от некоторой вершины a графа до всех остальных вершин этого графа.

Каждой вершине из сопоставим метку – минимальное известное расстояние до этой вершины от начальной вершины . Алгоритм работает пошагово – на каждом шаге он «посещает» одну вершину и пытается уменьшать метки. Работа алгоритма завершается, когда все вершины посещены.

Инициализация. Метка начальной вершины полагается равной 0, метки остальных вершин – бесконечности. Это отражает то, что расстояния от до других вершин пока неизвестны. Все вершины графа помечаются как непосещённые.

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

Пример

Рассмотрим выполнение алгоритма на примере графа, показанного на рисунке. Пусть требуется найти расстояния от 1-й вершины до всех остальных.

Кружками обозначены вершины, линиями – пути между ними (ребра графа). В кружках обозначены номера вершин, над ребрами обозначена их «цена» – длина пути. Рядом с каждой вершиной красным обозначена метка – длина кратчайшего пути в эту вершину из вершины 1.

Первый шаг. Рассмотрим шаг алгоритма Дейкстры для нашего примера. Минимальную метку имеет вершина 1. Её соседями являются вершины 2, 3 и 6.

Первый по очереди сосед вершины 1 – вершина 2, потому что длина пути до неё минимальна. Длина пути в неё через вершину 1 равна сумме кратчайшего расстояния до вершины 1, значению её метки, и длины ребра, идущего из 1-ой в 2-ую, то есть 0 + 7 = 7. Это меньше текущей метки вершины 2, бесконечности, поэтому новая метка 2-й вершины равна 7.

Аналогичную операцию проделываем с двумя другими соседями 1-й вершины – 3-й и 6-й.

Все соседи вершины 1 проверены. Текущее минимальное расстояние до вершины 1 считается окончательным и пересмотру не подлежит (то, что это действительно так, впервые доказал Э. Дейкстра). Вычеркнем её из графа, чтобы отметить, что эта вершина посещена.

Второй шаг. Шаг алгоритма повторяется. Снова находим «ближайшую» из непосещенных вершин. Это вершина 2 с меткой 7.

Снова пытаемся уменьшить метки соседей выбранной вершины, пытаясь пройти в них через 2-ю вершину. Соседями вершины 2 являются вершины 1, 3 и 4.

Первый (по порядку) сосед вершины 2 – вершина 1. Но она уже посещена, поэтому с 1-й вершиной ничего не делаем.

Следующий сосед вершины 2 – вершина 3, так как имеет минимальную метку из вершин, отмеченных как не посещённые. Если идти в неё через 2, то длина такого пути будет равна 17 (7 + 10 = 17). Но текущая метка третьей вершины равна 9<17, поэтому метка не меняется.

Ещё один сосед вершины 2 – вершина 4. Если идти в неё через 2-ю, то длина такого пути будет равна сумме кратчайшего расстояния до 2-ой вершины и расстояния между вершинами 2 и 4, то есть 22 (7 + 15 = 22). Поскольку 22< , устанавливаем метку вершины 4 равной 22.

Все соседи вершины 2 просмотрены, замораживаем расстояние до неё и помечаем её как посещенную.

Третий шаг. Повторяем шаг алгоритма, выбрав вершину 3. После её «обработки» получим такие результаты:

Дальнейшие шаги. Повторяем шаг алгоритма для оставшихся вершин. Это будут вершины 6, 4 и 5, соответственно порядку.

Завершение выполнения алгоритма. Алгоритм заканчивает работу, когда вычеркнуты все вершины. Результат его работы виден на последнем рисунке: кратчайший путь от вершины 1 до 2-й составляет 7, до 3-й – 9, до 4-й – 20, до 5-й – 20, до 6-й – 11.

const

maxn = 100;

infinity = maxlongint;

var

i,j,u,v,n,m,c,min,s,t:longint;

e,w:array[1..maxn,1..maxn]of longint;

ne,use,p,d:array[1..maxn]of longint;

begin

read(n,m,t,s);

for i:=1 to m do begin

read(u,v,c);

inc(ne[v]); e[v,ne[v]]:=u; //edges are inverted

w[v,u]:=c;

end;

for i:=1 to n do d[i]:=infinity;

d[s]:=0;

for i:=1 to n do begin

min:=infinity;

for j:=1 to n do if (use[j]=0)and(d[j]<min) then begin

min:=d[j]; u:=j;

end;

use[u]:=1;

for j:=1 to ne[u] do begin

v:=e[u,j];

if d[v]>d[u]+w[u,v] then begin

d[v]:=d[u]+w[u,v]; p[v]:=u;

end;

end;

end;

writeln(d[t]);

u:=t; write(u);

while u<>s do begin

u:=p[u]; write(' ',u);

end;

end.

Билет №39

События мыши и клавиатуры

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

Пусть имя графического элемента – ImageGraph, имя формы – Form1.

Событие «нажата кнопка мыши» (MouseDown).

procedure TForm1.ImageGraphMouseDown(Sender: TObject;

Button: TMouseButton; Shift: TShiftState; x, y: Integer);

Sender: объект–предок объекта, с которым произошло событие. Из этого объекта можно «выудить» наиболее общие для визуальных элементов управления на форме свойства и методы. Например:

ShowMessage(Sender.UnitName);

повлечёт появление на экране ExtCtrls – имя модуля (устройства, юнита), в котором класс TObject объекта Sender объявлен.

Другой пример:

ShowMessage(Sender.Name);

повлечёт ошибку на этапе компиляции. Нет у объекта Sender свойства Name.

Button: параметр перечисляемого типа, объявленного в модуле Controls:

type

TMouseButton = (mbLeft, mbRight, mbMiddle);

По именам возможных значений параметра понятно, какая из кнопок мыши нажата.

Shift: параметр, имеющий тип–множество, объявленный в модуле Classes:

type

TShiftState = set of (ssShift, ssAlt, ssCtrl, ssLeft, ssRight, ssMiddle, ssDouble);

Тип TShiftState используется обработчиками событий мыши и клавиатуры для выяснения состояния клавиш Alt, Ctrl, Shift клавиатуры и кнопок мыши в момент происхождения события.

Составляющие множество «флаги» имеют следующий смысл:

ssShift – клавиша Shift нажата.

ssAlt – клавиша Alt нажата.

ssCtrl – клавиша Ctrl нажата.

ssLeft – левая кнопка мыши нажата.

ssRight – правая кнопка мыши нажата.

ssMiddle – средняя кнопка мыши нажата.

ssDouble – мышь получила двойной щелчок.

x, y: координаты указателя мыши (в пикселях) относительно верхнего левого угла элемента, с которым произошло событие (в данном случае, ImageGraph).

Событие «перемещается указатель мыши» (MouseMove).

procedure TForm1.ImageGraphMouseMove(Sender: TObject;

Shift: TShiftState; x, y: Integer);

Параметры в дополнительных пояснениях не нуждаются

Событие «отпущена кнопка мыши» (MouseUp).

procedure TForm1.ImageGraphMouseUp(Sender: TObject;

Button: TMouseButton; Shift: TShiftState; x, y: Integer);

Параметры в дополнительных пояснениях не нуждаются.

Ссылки на модули Controls и Classes должны присутствовать в предложении uses.