Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Delphi

.pdf
Скачиваний:
27
Добавлен:
13.04.2015
Размер:
1.18 Mб
Скачать

3 ЯЗЫК ПРОГРАММИРОВАНИЯ Object Pascal

<имя типа-массива > = Array Of Array Of <тип элементов массива >;

Объявление динамических массивов – это

Var <идентификаторы массивов> : <имя типа-массива>;

или

Var <идентификаторы массивов> : Array Of <тип элементов массива>;

Нумерация элементов динамических массивов всегда начинается с нуля. Несмотря на то, что идентификаторы динамических массивов являются указателями на динамическую область памяти, использовать символ ^ после них ненужно. Размещение в памяти таких массивов осуществляется при помощи стандартных процедур и функций:

SetLength(Din, N[, M, …]) – выделяет под динамический массив Din память в N (для двухмерного массива – N ×M и т.д.) элементов и присваивает переменной Din указатель на эту память;

Finalize(Din) – освобождает память, выделенную под динамический массив Din, и переменной Din присваивает значение nil;

Copy(Din[, Index, N]): Pointer – создает копию массива Din, т.е. выделяет динамическую память, копирует в неё весь массив или N элементов исходного динамического массива Din, начиная с элемента Index, и возвращает указатель на новую выделенную область. Если Index больше максимального индекса массива, то область не выделяется, а указатель принимает значение nil. Например, сделать копию A2 массива A1 – это

A2:=Copy(A1);

П р и м е р 3.25 (динамический массив)

Type

T1 Array of Array of Integer;

Var

Int1,Int2 : T1;

x : Integer;

Begin

SetLength(Int1,5,3);

{Массив из 5 строк и 3 столбцов}

Int1[0,0]:=10; Int1[4,2]:=40;

{Инициализация первого и

 

 

 

последнего элементов}

Int2:=Int1;

{Указатель Int2 получает адрес указателя Int1,

 

 

при этом новая память не выделяется}

x:=Int2[0,0];

 

 

{Переменная x=10}

Int1:=nil;

 

{Освобождение динамической памяти,

 

 

эквивалентно оператору Finalize(Int1)}

end;

60

3.6 ОПИСАНИЯ ТИПОВ

Задание 6.

Работа с динамическими массивами

Цель задания

1.Получение практических навыков для работы с массивами.

2.Освоение динамического размещения данных.

Постановка задачи

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

– ввод элементов массива посредством таблицы (рис. 3.5) с контролем и предупреждением об ошибках ввода (рис. 3.6), третье – вывод обработанного массива (рис. 3.6).

Рис. 3.5 Ввод элементов массива

Рекомендации

Обе таблицы массивов целесообразно разместить на одной панели, которая должна появляться при нажатии на кнопку «Выделить память» (после этого кнопка должна исчезать или быть недоступной) и скрываться при нажатии на кнопку «Очистить». Не забудьте при этом высвободить динамическую память массивов. Начальное значение свойства Visible для панели и второй таблицы должно быть False, т.е. вначале панель и таблица результатов должны быть невидимыми. При нажатии на кнопку «Выделить память»

61

3 ЯЗЫК ПРОГРАММИРОВАНИЯ Object Pascal

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

Не забывайте, что первый индекс в массиве – это номер элементов строк, а в таблице TStringGrid – это номер элементов столбцов. Для того чтобы в таблицу можно было вводить данные, т.е. редактировать содержимое ячеек Cells, необходимо в свойствах Options установить значение goEditing=True. Для удобного перемещения по ячейкам таблицы – при помощи клавиши табуляции, надо установить goTabs=True.

Рис. 3.6

Диалоговые окна

– « сообщения об ошибках ввода»

Рис. 3.7 Вывод обработанного массива

Корректность ввода данных из таблицы TStringGrid надо контролировать по значению последнего параметра функции преобразования Val. Для вывода сообщений об ошибках преобразования можно использовать диалоговые окна стандартного модуля Dialogs и компонента TApplication:

62

3.6 ОПИСАНИЯ ТИПОВ

ShowMessage('<сообщение>') – процедура, создающая информационное окно с заданным сообщением, названием приложения в заголовке окна и с единственной кнопкой «OK»;

MessageDlg('<сообщение>', <тип рисунка>, [<множество кнопок>],0)

– функция, создающая информационное окно с заданным сообщением, рисунком и набором кнопок. Пример такого окна показан на рис. 3.6. Тип рисунка в окне определяется стандартными константами, например, константа mtError – рисунок «ошибка», mtInformation – рисунок «информация». Множество кнопок задается непосредственно в виде множества соответствующих констант, например, [mbCancel,mbOK] – кнопки «Cancel» и «OK». Функция принимает значение константы, соответствующей нажатию той или иной кнопки. Описание всех параметров функции смотрите через контекстную подсказку F1. Например, mrCancel – бала нажата кнопка «Cancel», mrOK – «OK». Следующий пример, иллюстрирует сказанное:

case MessageDlg('Что выбрать?', mtConfirmation,

 

[mbOK,mbCancel], 0) of

mrOk

: Edit1.Text:='Выбрано OK';

mrCancel : Edit1.Text:='Выбрано Cancel'; end

В примере 3.36 можно найти использование рассматриваемой функции с преобразованием идентификаторов кнопок к целому типу - Var res:

Word;

Application.MessageBox('<сообщение>', '[<заголовок окна>]', <идеентификатор кнопки>) – функция, создающая информационное окно с заданным сообщением и заголовком окна, содержащая кнопки, указанные идентификатором. Например, при идентификаторе MB_OKCANCEL показываются две кнопки «OK» и «Cancel». Функция принимает значение равное 1, если нажать на кнопку «OK», и 2, если нажать на кнопку «Cancel». Описание всех параметров функции можно получить через контекстную подсказку F1.

Если обработка массива предусматривает сортировку его элементов, то наиболее удобно это сделать «методом пузырька». Суть метода заключается в следующем. Пусть имеется массив элементов a0,a1…a i…a n. Их надо отсортировать по неубыванию или по невозрастанию. Поступаем так, сравниваем пару элементов ai и ai-1, при необходимости, в соответствие с условием задачи, меняем их местами и увеличиваем индекс i на 1. Делаем это для всех i от 1 до n. Такой проход обеспечит перемещение экстремального элемента (максимального или минимального, в

63

3 ЯЗЫК ПРОГРАММИРОВАНИЯ Object Pascal

зависимости от условия сравнения) в конец строки. Если сделать несколько подобных проходов (не более n), то сортируется вся строка.

Имейте ввиду, что поменять местами элементы массива можно только при помощи дополнительной «рабочей» переменной. Её можно назвать «буфером обмена».

На Рис. 3.7 кнопка «Сортировать элементы» содержит рисунок. Такая кнопка устанавливается компонентом:

TBitBtn – находится на странице Additional. Рисунок на кнопке – это графический фай типа *.bmp, который выбирается и подключается через свойство Glyph (символический знак).

Варианты задания:

1.Дан двухмерный массив в виде квадратной матрицы. Найти определитель матрицы.

2.Дан двухмерный массив. Элементами массива являются целые числа. Упорядочить строки массива по не убыванию элементов третьего столбца.

3.Дан двухмерный массив. Элементами массива являются целые числа. Упорядочить строки массива по не убыванию элементов пятого столбца.

4.Дан одномерный массив целых чисел. Записать в этот же массив сначала все отрицательные числа и нули, затем все положительные, сохраняя порядок их следования.

5.Дан двухмерный массив. Элементами массива являются целые числа. Упорядочить столбцы массива по не возрастанию элементов второй строки.

6.Дан одномерный массив целых чисел. Записать в этот же массив сначала все положительные числа и нули, затем все отрицательные числа, сохраняя порядок их следования.

7.Дан двухмерный массив в виде квадратной матрицы. Элементами массива являются целые числа. Упорядочить элементы на диагонали матрицы по возрастанию.

8.Дан двухмерный массив в виде квадратной матрицы. Элементами матрицы являются вещественные числа. Найти транспонированную матрицу, т.е. поменять метами строки и столбцы

9.Упорядочить по не убыванию одномерный массив целых чисел.

10.Упорядочить по невозрастанию одномерный массив вещественных чисел.

Контрольные вопросы для сдачи лабораторной работы:

1.Какого типа могут быть индексы и элементы массива?

2.Каков порядок обработки элементов двухмерного массива в двойном цикле?

64

3.6ОПИСАНИЯ ТИПОВ

3.Что такое указатель? Как он описывается? Что содержится в памяти под переменными ссылочного типа?

4.Как выделить и освободить память для типа-массива?

5.Что надо сделать, чтобы можно было редактировать ячейки таблицы

StringGrid?

6.Как поместить рисунок на кнопку?

7.Как вывести сообщение в какое-либо диалоговое окно?

8.В чем заключается идея метода пузырька?

3.6.6Описание записей (Record, With)

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

Type <идентификатор типа>= Record

<идентификатор поля 1>: <тип элемента 1>; <идентификатор поля 2>: <тип элемента 2>;

End;

Var <идентификатор записи> : <идентификатор типа>;

Если какие-либо поля имеют один и тот же тип, то их идентификаторы можно перечислять через запятую, например, <идентификатор поля 1>, <идентификатор поля 2>: <тип элементов>;

При объявлении переменных типа Record полям записи можно присваивать начальные значения через двоеточие:

Var <идентификатор записи>: <идентификатор типа > = (<идентификатор поля 1>: <значение элемента 1>; <идентификатор поля 2>: <значение элемента 2>);

П р и м е р 3.26

Описание характеристик компьютеров группы пользователей

 

Type

 

OS=(MS_DOS, Linux, Windows98, WindowsNT);

{тип OS

(операционная система) состоит из четырёх констант}

CPU=(Pentium1, Pentium2, Pentium3, Pentium4); Computer = Record {описание характеристик компьютера}

OperatingSystem: OS; {поле OperationSystem в записи Computer

имеет тип OS}

Processor : CPU;

65

3 ЯЗЫК ПРОГРАММИРОВАНИЯ Object Pascal

Price

:

Double;

MadeIn

:

String;

End;

Var Users: Array[1..50] of Computer;

Каждый из 50 элементов массива Users является записью и будет содержать информацию о четырёх разнотипных характеристиках персональных компьютеров. Занести данные о компьютере, например, третьего пользователя можно следующим образом:

Users[3].OperatingSystem:=Windows98;

Users[3].Processor:=Pentium2;

Users[3].Price:=2370;

Users[3].MadeIn:='Taiwan';

Такой доступ к полям записи называется доступом по квалификационному имени. Идентификатор записи (в данном случае – это Users[3]) и идентификатор поля записи разделяются точкой.

Операции присваивания для записей можно делать компактно, если использовать оператор присоединения:

With <список идентификаторов записей> Do begin <операторы с идентификаторами полей>

end;

П р и м е р 3.27

With Users[3], Users[5] Do Begin OperationSystem := Windows98; Processor:= Pentium2;

Price:= 2370; MadeIn:='Taiwan';

end;

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

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

При использовании операторов With необходимо придерживаться следующих правил: не вводите идентификаторы полей записи, имена

66

3.6 ОПИСАНИЯ ТИПОВ

которых совпадали бы с идентификаторами свойств и методов каких-либо компонент; не охватывайте оператором With очень большие области кодов.

Задание 7.

Работа с записями

Цель задания

1. Получение навыков программирования с использованием записей.

Постановка задачи

Ввести список учебной группы, включающий 5 человек. Для каждого студента указать дату рождения, год поступления, курс, группу, оценки при поступлении. Информацию о каждом студенте оформить в виде записи. Совокупность записей объединить в массив. Каждую запись заполнять оператором With. Согласно варианту задания вывести обработанный список. Интерфейс приложения оформить по своему вкусу.

Варианты задания:

1.Вывести фамилии студентов начинающиеся на букву А с их оценками.

2.Вывести фамилии студентов начинающиеся на букву Б с их датой рождения.

3.Вывести оценки студентов, фамилии которых начинаются с букв В и Г.

4.Вывести фамилии и даты рождения студентов, не получивших ни одной оценки “3”.

5.Упорядочить список студентов по среднему баллу и вывести его.

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

7.Вывести средний балл группы и вывести список студентов, имеющих средний балл ниже среднего балла группы.

8.Вывести список студентов, упорядоченный по алфавиту.

9.Вывести список студентов, упорядоченный по месяцу рождения.

10.Вывести список студентов, упорядоченный по дате рождения.

Контрольные вопросы для сдачи лабораторной работы:

1.Чем отличается запись от массива?

2.Как организовать обращение к заданному полю записи?

3.Зачем нужен оператор присоединения?

4.Может ли поле записи быть записью? Приведите пример описания.

3.6.7Преобразование типов

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

67

3 ЯЗЫК ПРОГРАММИРОВАНИЯ Object Pascal

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

 

П р и м е р 3.28

Type

 

ByteRec = Record

 

Lo, Hi : Byte

{размер записи = 2 байта}

end;

 

Var

 

W : Word;

{размер 2 байта}

B : Byte;

{размер 1 байт}

Begin

 

...

B:=ByteRec(W).Lo;{преобразование переменной типа Word в запись из двух байт и присвоение первого байта (поле Lo)

переменной типа Byte} ByteRec(W).Hi:=0;{преобразование переменной типа Word в запись из двух байт и присвоение второму байту (поле Hi)

нулевого значения}

...

Подобное преобразование возможно для случая перечислимых типов не зависимо от их размеров. Стандартные функции преобразования строковых и арифметических типов были описаны ранее в разделах 3.2.2 и 3.3.5.

3.6.8 Размещение данных в файлах

Данные можно хранить на внешних запоминающих устройствах. Обычно для этого используют гибкие и жёсткие (винчестеры) магнитные диски. Любой магнитный диск должен быть подготовлен, т.е. отформатирован для записи. Форматирование дисков включает в себя два уровня – физический (полное форматирование) и логический (быстрое форматирование):

1 – ( физический уровень) головки дисководов, двигаясь к центру вращающегося диска, размечают на нем магнитные концентрические дорожки, состоящие из блоков (секторов) как это показано на Рис. 3.8 Выявляются и изолируются нерабочие блоки.

2 – ( логический уровень) в нулевом блоке делается загрузочная запись

– BOOTсектор, в котором содержится информация о количестве дорожек, блоков, наличии операционной системы и др. Начиная с первого блока, записывается таблица расположения файлов – FAT вместе со своей копией, далее организуется корневой каталог – ROOT.

Блоки объединяются в кластеры. Один кластер состоит от 2 до 64 блоков. Данные записываются и читаются кластерами (см. рис. 3.9). Новый файл всегда начинается с нового кластера. При частом удалении и записи

68

3.6 ОПИСАНИЯ ТИПОВ

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

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

.

Рис. 3.8 Разбивка диска на дорожки и блоки

Рис. 3.9 Организация файлов на диске для 4-блочных кластеров

С точки зрения Object Pascal Существуют три категории файлов: текстовые, типизированные и файлы без типа. Мы будем рассматривать только текстовые файлы.

Файлы, состоящие из строк, называются текстовыми. Компоненты таких файлов могут быть символьного, строкового и арифметического типа. Признак конца строки (код #13) вставляется клавишей Enter при вводе строк с клавиатуры или оператором WriteLn при записи данных из

69

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]