Рейтинг@Mail.ru

 

 

 

 

 

 

.: Учебник по Delphi 7 для начинающих :.

<< НазадСодержаниеВперед >>

маркированный список Глава 5. Массивы

Глава 5

Массивы

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

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

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

Имя: array [нижний_индекс. .верхний_индекс] of тип

где:

  • имя — имя массива;
  • array — зарезервированное слово языка Delphi, обозначающее, что объявляемое имя является именем массива;
  • нижний_индекс и верхний_и«декс — целые константы, определяющие диапазон изменения индекса элементов массива и, неявно, количество элементов (размер) массива;
  • тип — тип элементов массива.

Примеры объявления массивов:

temper:array[1..31] of real;

коef:array[0. .2] of integer;

name:array[1..30] of string[25];

При объявлении массива удобно использовать именованные константы. Именованная константа объявляется в разделе объявления констант, который обычно располагают перед разделом объявления переменных. Начинается раздел объявления констант словом const. В инструкции объявления именованной константы указывают имя константы и ее значение, которое отделяется от имени символом "равно". Например, чтобы объявить именованную константу нв, значение которой равно 10, в раздел const надо записать инструкцию: нв=ю. После объявления именованной константы ее можно использовать в программе как обычную числовую или символьную константу. Ниже в качестве примера приведено объявление массива названий команд-участниц чемпионата по футболу, в котором используются именованные константы.

const

NT = 18; // число команд

SN = 25; // предельная длина названия команды var

team: array[1..NT] of string[SN];

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

team [ 1] := 'Зенит';

d := koef[l]*koef[l]-4*koef[2]*koef[1];

ShowMessage(name[n+1]);

temper[i] := StrToFloat(Edit1.text);

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

Имя:array[нижний_индекс..верхний_индекс] of тип = (список);

где список — разделенные запятыми значения элементов массива. Например:

a: array[10] of integer = (0,0,0,0,0,0,0,0,0,0);

Team: array[1..5] of String[10]=

('Зенит','Динамо','Спартак','Ротор','СКА');

Обратите внимание, что количество элементов списка инициализации должно соответствовать размерности массива. Если это будет не так, то компилятор выведет сообщения об ошибке: Number of elements differs from declaration (количество элементов не соответствует указанному в объявлении).

При попытке инициализировать локальный массив компилятор выводит сообщение об ошибке: Cannot initialize local variables (локальная переменная не может быть инициализирована). Локальный массив можно инициализировать только во время работы программы, например, так:

for i := 1 to 10 do

a[i]:= 0;

Операции с массивами

Типичными операциями при работе с массивами являются:

  • вывод массива;
  • ввод массива;
  • поиск максимального или минимального элемента массива;
  • поиск заданного элемента массива;
  • сортировка массива.

Вывод массива

Под выводом массива понимается вывод на экран монитора (в диалоговое окно) значений элементов массива.

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

В качестве примера на рис. 5.1 приведено диалоговое окно приложения, которое демонстрирует инициализацию и процесс вывода значений элементов массива в поле метки. Программа выводит пронумерованный список футбольных команд. Следует обратить внимание, что для того чтобы список команд выглядел действительно как список, свойству Label1.AutoSize нужно присвоить значение False (присвойте свойству Label1.AutoSize значение True и посмотрите, как будет работать программа). Текст программы приведен в листинге 5.1.

Рис. 5.1. Форма и диалоговое окно приложения Вывод массива

Листинг 5.1. Инициализация и вывод массива

unit outar_;

interface

uses

Windows, Messages, SysUtils, Variants,

Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls;

type

TForm1 = class(TForm)

Button1: TButton;

Label1: TLabel;

procedure ButtonlClick(Sender: TObject);

private

{ Private declarations } public

{ Public declarations } end;

var

Form1: TForm1;

implementation

($R *.dfm}

const

NT = 5;

var

team: array[1..NT] of string[10] =

('Зенит','Динамо','Ротор','Спартак','СКА'

procedure TForml.ButtonlClick(Sender: TObject);

var

st:string; // список команд

i:integer; // индекс, номер элемента массива

begin

// формирование списка для отображения в форме

for i:=l to NT do st := st + IntToStr(i)+ ' '

+ team[i] + #13; // вывод списка Label1.Caption := st;

end;

end.

Ввод массива

Под вводом массива понимается процесс получения от пользователя (или из файла) во время работы программы значений элементов массива.

"Лобовое" решение задачи ввода элементов массива — для каждого элемента массива создать поле ввода. Однако если требуется ввести достаточно большой массив, то такое решение неприемлемо. Представьте форму, например, с десятью полями редактирования!

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

StringGrid И Memo.

Использование компонента StringGrid

Для ввода массива удобно использовать компонент StringGrid. Значок компонента StringGrid находится на вкладке Additional (рис. 5.2).

Рис. 5.2. Компонент StringGrid

Компонент StringGrid представляет собой таблицу, ячейки которой содержат строки символов. В табл. 5.1 перечислены некоторые свойства компонента StringGrid.

Таблица 5.1. Свойства компонента StringGrid

Свойство
Определяет
Name
Имя компонента. Используется в программе для доступа к свойствам компонента
Свойство
Определяет
ColCount
Количество колонок таблицы
RowCount
Количество строк таблицы
Cells
Соответствующий таблице двумерный массив. Ячейка таблицы, находящаяся на пересечении столбца номер col и строки номер row определяется элементом cells [col, row]
FixedCols
Количество зафиксированных слева колонок таблицы. Зафиксированные колонки выделяются цветом и при горизонтальной прокрутке таблицы остаются на месте
FixedRows
Количество зафиксированных сверху строк таблицы. Зафиксированные строки выделяются цветом и при вертикальной прокрутке таблицы остаются на месте
Options . goEditing
Признак допустимости редактирования содержимого ячеек таблицы. True — редактирование разрешено, False — запрещено
Options . goTab
Разрешает (True) или запрещает (False) использование клавиши <ТаЬ> для перемещения курсора в следующую ячейку таблицы
Options . GoAlways-ShowEditor
Признак нахождения компонента в режиме редактирования. Если значение свойства False, то для того, чтобы в ячейке появился курсор, надо начать набирать текст, нажать клавишу <F2> или сделать щелчок мышью
DefaultColWidth
Ширину колонок таблицы
DefaultRowHeight
Высоту строк таблицы
GridLineWi-dth
Ширину линий, ограничивающих ячейки таблицы
Left
Расстояние от левой границы поля таблицы до левой границы формы
Top
Расстояние от верхней границы поля таблицы до верхней границы формы
Height
Высоту поля таблицы
Width
Ширину поля таблицы
Font
Шрифт, используемый для отображения содержимого ячеек таблицы
ParentFont
Признак наследования характеристик шрифта формы

В качестве примера использования компонента stringGrid для ввода массива рассмотрим программу, которая вычисляет среднее арифметическое значение элементов массива. Диалоговое окно программы приведено на рис. 5.3. Компонент stringGrid используется для ввода массива, компоненты Label1 и Label2 — для вывода пояснительного текста и результата расчета, Buttoni — для запуска процесса расчета.

Рис. 5.3. Диалоговое окно программы Ввод и обработка массива

Добавляется компонент stringGrid в форму точно так же, как и другие компоненты. После добавления компонента к форме нужно выполнить его настройку в соответствии с табл. 5.2. Значения свойств Height и width следует при помощи мыши установить такими, чтобы размер компонента был равен размеру строки.

Текст программы приведен в листинге 5.2.

Таблица 5.2. Значения свойств компонента StringGrid1

Свойство
Значение
ColCount
5
FixedCols
0
RowCount
1
DefaultRowHeight
24
Height
24
DefaultColWidth
64
Width
328
Options . goEditing
True
Options . AlwaysShowEditing
True
Options .goTabs
True

 

Листинг 5.2. Ввод и обработка массива целых чисел

unit getar_;

interface

uses

Windows, Messages, SysUtils, Variants,

Classes, Graphics, Controls, Forms, Dialogs, Grids, StdCtrls;

type

TForm1 = class(TForm)

Label1: TLabel;

StringGridl: TStringGrid;

Button1: TButton;

Label2: TLabel;

procedure ButtonlClick(Sender: TObject); private

{ Private declarations }

public

{ Public declarations }

end;

var

Form1: TForml ;

implementation

{$R *.dfm}

procedure TForml.ButtonlClick(Sender: TObject); var

a : array[1..5] of integer; // массив

summ: integer; // сумма элементов

sr: real; // среднее арифметическое

i: integer; // индекс

begin

// ввод массива

// считаем, что если ячейка пустая, то соответствующий

// ей элемент массива равен нулю

for i:= 1 to 5 do

if Length(StringGridl.Cells[i-1, 0]) <>0

then a[i] := StrToInt(StringGridl.Cells[i-1,0])

else a[i] := 0;

// обработка массива

summ := 0;

for i :=1 to 5 do

summ := summ + a[i]; sr := summ / 5;

У вывод результата Label2.Caption :=

'Сумма элементов: ' + IntToStr(summ)

+ #13+ 'Среднее арифметическое: ' + FloatToStr(sr);

end;

end.

После пробных запусков программы возникает желание внести изменения в процесс ввода массива. Так, было бы неплохо, чтобы курсор автоматически переходил в следующую ячейку таблицы, например, в результате нажатия клавиши <Enter>. Сделать это можно при помощи процедуры обработки события onKeyPress. На эту же процедуру можно возложить задачу фильтрации вводимых в ячейку таблицы данных. В нашем случае надо разрешить ввод в ячейку только цифр.

Текст процедуры обработки события OnKeyPress приведен в листинге 5.3. Следует обратить внимание на свойство Col, которое во время работы программы содержит номер колонки таблицы, в которой находится курсор. Это свойство можно также использовать для перемещения курсора в нужную ячейку таблицы. Однако нужно учитывать, что колонки таблицы, впрочем, как и строки, нумеруются с нуля.

Листинг 5.3. Процедура обработки события OnKeyPress

procedure TForm1.StringGridlKeyPress(Sender: TObject;

var Key: Char);

begin

case Key of

#8,'0'..'9' : ; // цифры и клавиша <Backspace>

#13: // клавиша <Enter>

if StringGridl.Col < StringGridl.ColCount — 1

then StringGridl.Col := StringGridl.Col + 1;

else key := Chr(0); // остальные символы запрещены

end;

end;

Если нужно ввести массив дробных чисел (a: array [1. .5] of real), то процедура обработки события OnKeyPress несколько усложнится, т. к. помимо цифр допустимыми символами являются символ-разделитель (запятая или точка — зависит от настройки Windows) и минус. С целью обеспечения некоторой дружественности программы по отношению к пользователю можно применить трюк: подменить вводимый пользователем неверный разделитель верным. Определить, какой символ-разделитель допустим в текущей настройке Windows, можно, обратившись к глобальной переменной Decimaiseparator.

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

Листинг 5.4. Ввод и обработка массива дробных чисел

unit. getar_1; interface

uses

Windows, Messages, SysUtils, Variants, Classes,

Graphics, Controls, Forms, Dialogs, Grids, StdCtrls;

type

TForm1= class(TForm)

Label1: TLabel;

StringGrid1: TStringGrid;

Button1: TButton;

Label2: TLabel;

procedure Button1ClicktSender: TObject);

procedure StringGridlKeyPress(Sender: TObject; var Key: Char);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ButtonlClick(Sender: TObject);

var

a : array[1..5] of real; // массив

suram: real; // сумма элементов

sr: real; // среднее арифметическое

i: integer; // индекс

begin

// ввод массива

// считаем, что если ячейка пустая, то соответствующий

// ей элемент массива равен нулю

for i:= 1 to 5 do

if Length(StringGridl.Cells[i-l,0])<>0

then a[i] := StrToFloat(StringGridl.Cells[i-1, 0]) else a[i] := 0;

// обработка массива

summ := 0;

for i :=1 to 5 do

summ := summ + a[i]; sr := summ / 5;

// вывод результата

Label2.Caption :=

'Сумма элементов: ' + FloatToStr(summ)

+ #13+ 'Среднее арифметическое: ' + FloatToStr(sr); end;

'/ Функция обеспечивает ввод в ячейку только допустимых символов

procedure TForm1.StringGridlKeyPress(Sender: TObject; var Key: Char);

begin

case Key of

#8,'0'..'9' : ; // цифры и <Backspace>

#13: // клавиша <Enter>

if StringGridl.Col < StringGridl.ColCount - 1

then StringGridl.Col := StringGridl.Col + 1; '.',',':

// разделитель целой и дробной частей числа

begin

if Key <> DecimalSeparator then

Key := DecimalSeparator; // заменим разделитель

// на допустимый

if Pos(StringGridl.Cells[StringGridl.Col,0],

DecimalSeparator) <> 0

then Key := Chr(O); // запрет ввода второго

// разделителя end;

' -' : // минус можно ввести только первым символом,

// т. е. когда ячейка пустая

if Length(StringGrid1.Cells[StringGrid1.Col, 0]) <>0 then

Key := Chr(0) ;

else // остальные символы запрещены

key := Chr(0);

end;

end;

end.

Использование компонента Memo

В некоторых случаях для ввода массива можно использовать компонент Memo. Компонент Memo позволяет вводить текст, состоящий из достаточно большого количества строк, поэтому его удобно использовать для ввода символьного массива. Компонент Memo добавляется в форму обычным образом. Значок компонента находится на вкладке Standard (рис. 5.4).

Рис. 5.4. Компонент Memo

В табл. 5.3 перечислены некоторые свойства компонента Memo.

Таблица 5.3. Свойства компонента Memo

Свойство
Определяет
Name
Имя компонента. Используется в программе для доступа к свойствам компонента
Text
Текст, находящийся в поле Memo. Рассматривается как единое целое
Lines
Текст, находящийся в поле Memo. Рассматривается как совокупность строк. Доступ к строке осуществляется по номеру
Lines .Count
Количество строк текста в поле Memo
Left
Расстояние от левой границы поля до левой границы формы
Top
Расстояние от верхней границы поля до верхней границы формы
Height
Высоту поля
Width
Ширину поля
Font
Шрифт, используемый для отображения вводимого текста
ParentFont
Признак наследования свойств шрифта родительской формы

При использовании компонента Memo для ввода массива значение каждого элемента массива следует вводить в отдельной строке и после ввода каждого элемента массива нажимать клавишу <Enter>.

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

Следующая программа, текст которой приведен в листинге 5.5, демонстрирует использование компонента Memo для ввода символьного массива.

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

for i:=l to SIZE do

a [ i ]:= Memol.Lines[i];

где:

  • SIZE — именованная константа, определяющая размер массива;
  • а — массив;
  • Memol — имя Memo-компонента;
  • Lines — свойство компонента Memo, представляющее собой массив, каждый элемент которого содержит одну строку находящегося в поле Memo текста.

Форма программы приведена на рис. 5.5. Помимо поля Memo она содержит командную кнопку (Buttonl), при щелчке на которой выполняется ввод значений элементов массива из поля Memo.

Рис. 5.5. Диалоговое окно приложения Ввод массива

Листинг 5.5. Ввод массива строк из компонента Memo

unit fr_memo_; interface

uses

Windows, Messages, SysUtils, Classes,

Graphics, Controls, Forms, Dialogs, Menus, StdCtrls;

type

TForm1 = class(TForm)

Memo1: TMemo;

Button1: TButton;

Label1: TLabel;

procedure ButtonlClick(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Forml: TForm1;

implementation

($R *.DFM}

procedure TForml .ButtonlClick(Sender: TObject);

const

SIZE=5; // размер массива var

a:array[l..SIZE]of string[30]; //массив

n: integer; // количество строк, введенных в поле Memo

i:integer; // индекс элемента массива

st:string;

begin

n:=Memo1.Lines.Count;

if n = 0 then begin

ShowMessage('Исходные данные не введены!');

Exit; // выход из процедуры обработки события

end;

// в поле Memo есть текст

if n > SIZE then begin

ShowMessage('Количество строк превышает размер массива.');

n:=SIZE; // будем вводить только первые SIZE строк

end;

for i:=1 to n do

a[i]:=Form1.Memol.Lines[i-1]; // строки Memo пронумерованы с нуля

// вывод массива в окно сообщения

if n > 0 then begin

st:='Введенный массив:'+#13;

for i: =1 to n do

st:=st+IntToStr(i)+' '+ a[i]+f13; ShowMessage(st);

end;

end;

end.

Основную работу выполняет процедура TForm1.Button1Click, которая сначала проверяет, есть ли в поле Memo1 текст. Если текст есть (в этом случае значение свойства Lines.Count больше нуля), то процедура сравнивает количество введенных строк и размер массива. Если это количество превышает размер массива, то программа изменяет значение п, тем самым подготавливает ввод только первых SIZE строк.

На рис. 5.6 приведен вид диалогового окна приложения Ввод массива. После щелчка на командной кнопке Ввод появляется окно (рис. 5.7), которое содержит значения элементов массива, полученные из Memo-поля.

Рис. 5.6. Окно приложения Ввод массива

Рис. 5.7. Массив, введенный из Memo-поля

Поиск минимального (максимального) элемента массива

Задачу поиска минимального элемента массива рассмотрим на примере массива целых чисел.

Алгоритм поиска минимального (максимального) элемента массива довольно очевиден: сначала делается предположение, что первый элемент массива является минимальным (максимальным), затем остальные элементы массива последовательно сравниваются с этим элементом. Если во время очередной проверки обнаруживается, что проверяемый элемент меньше (больше) принятого за минимальный (максимальный), то этот элемент становится минимальным (максимальным) и продолжается проверка оставшихся элементов.

Диалоговое окно приложения поиска минимального элемента массива содержит соответствующим образом настроенный компонент stringGridi, который применяется для ввода элементов массива, два поля меток (Label1 и Labeia), использующиеся для вывода информационного сообщения и результата работы программы, и командную кнопку (Buttonl), при щелчке на которой выполняется поиск минимального элемента массива. В табл. 5.4 приведены значения свойств компонента stringGridi.

Таблица 5.4. Значения свойств компонента stringGridi

Свойство
Значение
ColCount
005
FixedCols
000
RowCount
001
DefaultRowHeight
024
Height
024
DefaultColWidth
064
Width
328
Options . goEditing
True
Options . AlwaysShowEditing
True
Options .goTabs
True

В листинге 5.6 приведена процедура обработки события Onclick для командной кнопки Button1, которая вводит массив, выполняет поиск мини-мального элемента и выводит результат — номер и значение минимального элемента массива.

Листинг 5.6. Поиск минимального элемента массива

unit lookmin_;

interface

Windows, Messages, SysUtils, Classes, Graphics,

Controls, Forms, Dialogs, StdCtrls, Grids;

type

TForm1 = class(TForm)

Label1: TLabel;

Button1: TButton;

Label2: TLabel;

StringGridl: TStringGrid;

procedure ButtonlClick(Sender: TObject); private

{Private declarations )

public

{ Public declarations }

end;

var

Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.ButtonlClick(Sender: TObject);

const

SIZE=5;

var

a:array[l..SIZE]of integer; // массив целых

min:integer; // номер минимального элемента массива

i:integer; // номер элемента, сравниваемого с минимальным

begin

// ввод массива for i:=1 to SIZE do

a[i]:=StrToInt(StringGridl.Cells[i-1,0]);

// поиск минимального элемента

min:=1; // пусть первый элемент минимальный

for i:=2 to SIZE do

if a[i]< a[min]then min:=i;

// вывод результата

label2.caption:='Минимальный элемент массива:'

+IntToStr(a[min] +#13+'Номер элемента:'+ IntToStr(min);

end;

end.

На рис. 5.8 приведен вид диалогового окна приложения после щелчка на кнопке Поиск.

Рис. 5.8. Окно приложения Поиск минимального элемента массива

Поиск в массиве заданного элемента

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

Для организации поиска в массиве могут быть использованы различные алгоритмы. Наиболее простой — это алгоритм простого перебора. Поиск осуществляется последовательным сравнением элементов массива с образцом до тех пор, пока не будет найден элемент, равный образцу, или не будут проверены все элементы. Алгоритм простого перебора применяется, если элементы массива не упорядочены.

Алгоритм простого перебора

Ниже приведен текст программы поиска в массиве целых чисел. Перебор элементов массива осуществляется инструкцией repeat, в теле которой инструкция if сравнивает текущий элемент массива с образцом и присваивает переменной found значение true, если текущий элемент и образец равны.

Цикл завершается, если в массиве обнаружен элемент, равный образцу (в этом случае значение переменной found равно true), или если проверены все элементы массива. По завершении цикла по значению переменной found можно определить, успешен поиск или нет.

Вид диалогового окна программы Поиск в массиве приведен на рис. 5.9.

Рис. 5.9. Диалоговое окно программы Поиск в массиве

Щелчок на командной кнопке Поиск (Buttoni) запускает процедуру TForm1.Button1Click (ее текст приведен в листинге 5.7), которая из компонента stringGridi вводит массив, а из поля редактирования Edit2 — число (образец). Затем выполняется проверка, содержит ли массив введенное число. После завершения проверки процедура showMessage выводит сообщение о результате поиска.

Листинг 5.7. Поиск в массиве

unit s_found_; interface

uses

Windows, Messages, SysUtils, Classes,

Graphics, Controls, Forms, Dialogs,

StdCtrls, Grids;

type

TForm1 = class(TForm)

Label1: TLabel;

Label2: TLabel;

Button1: TButton;

Edit2: TEdit;

StringGridi: TStringGrid;

procedure ButtonlClick(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations )

end;

var

Form1: TForm1 ;

implementation

{$R *.DFM}

{ поиск в массиве перебором }

procedure TForml.ButtonlClick(Sender: TObject);

const

SIZE=5; var

a: array[1..SIZE] of integer; //массив

obr: integer; // образец для поиска

found: boolean; // TRUE — совпадение образца с элементом

// массива

i: integer; // индекс элемента массива

begin

// ввод массива for i:=l to SIZE do

a[i] := StrToInt(StringGridl.Cells[i-1,0]);

// ввод образца для поиска

obr := StrToInt(edit2.text);

// поиск

found := FALSE; // пусть нужного элемента в массиве нет

i:= 1;

repeat

if a[i] = obr

then found := TRUE else i := i+1;

until (i > SIZE) or (found = TRUE);

if found

then ShowMessage('Совпадение с элементом номер '

+IntToStr(i)+#13+'Поиск успешен.')

else ShowMessage('Совпадений с образцом нет.');

end;

end.

Очевидно, что чем больше элементов в массиве и чем дальше расположен нужный элемент от начала массива, тем дольше программа будет искать необходимый элемент.

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

Метод бинарного поиска

На практике довольно часто производится поиск в массиве, элементы которого упорядочены по некоторому критерию (такие массивы называются упорядоченными). Например, массив фамилий, как правило, упорядочен по алфавиту, массив данных о погоде — по датам наблюдений. В случае, если массив упорядочен, то применяют другие, более эффективные по сравнению с методом простого перебора алгоритмы, один из которых — метод бинарного поиска.

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

Метод (алгоритм) бинарного поиска реализуется следующим образом:

1. Сначала образец сравнивается со средним (по номеру) элементом массива (рис. 5.10, а).

  • Если образец равен среднему элементу, то задача решена.
  • Если образец больше среднего элемента, то это значит, что искомый элемент расположен ниже среднего элемента (между элементами с номерами sred+1 и niz), и за новое значение verb принимается sred+i, а значение niz не меняется (рис. 5.10, б).
  • Если образец меньше среднего элемента, то это значит, что искомый элемент расположен выше среднего элемента (между элементами с номерами verh и sred-1), и за новое значение niz принимается sred-1, а значение verh не меняется (рис. 5.10, в).

a

б

в

Рис. 5.10. Выбор среднего элемента массива при бинарном поиске

Рис. 5.11. Алгоритм бинарного поиска в упорядоченном по возрастанию массиве

2. После того как определена часть массива, в которой может находиться искомый элемент, по формуле (niz-verh) /2+verh вычисляется новое значение sred и поиск продолжается.

Алгоритм бинарного поиска, блок-схема которого представлена на рис. 5.11, заканчивает свою работу, если искомый элемент найден или если перед выполнением очередного цикла поиска обнаруживается, что значение verh больше, чем niz.

Вид диалогового окна программы Бинарный поиск в массиве приведен на рис. 5.12. Поле метки Label3 используется для вывода результатов поиска и протокола поиска. Протокол поиска выводится, если установлен флажок выводить протокол. Протокол содержит значения переменных verh, niz, sred. Эта информация, выводимая во время поиска, полезна для понимания сути алгоритма.

Рис. 5.12. Диалоговое окно программы Бинарный поиск в массиве

В форме приложения появился новый компонент, который до этого момента в программах не использовался, — флажок (компонент CheckBox). Значок компонента checkBox находится на вкладке Standard (рис. 5.13). Добавляется к форме он точно так же, как и другие компоненты. Свойства компонента CheckBox перечислены в табл. 5.5.

Таблица 5.5. Свойства компонента CheckBox

Свойство
Определяет
Name
Имя компонента. Используется в программе для доступа к свойствам компонента
Caption
Текст, поясняющий назначение флажка
Checked
Состояние, внешний вид флажка: если флажок установлен (в квадратике есть "галочка"), то checked = TRUE; если флажок сброшен (нет "галочки"), то Checked=FALSE
State
Состояние флажка. В отличие от свойства Checked, позволяет различать установленное, сброшенное и промежуточное состояния. Состояние флажка определяют константы:

cbChecked (установлен); cbGrayed (серый, неопределенное состояние); cbUnChecked (сброшен)

AllowGrayed
Может ли флажок быть в промежуточном состоянии: если AllowGrayed = FALSE, то флажок может быть только установленным или сброшенным;

если AllowGrayed = TRUE, то допустимо промежуточное состояние

 

Свойство
Определяет
Left

Top

Height

Width

Font

ParentFont

Расстояние от левой границы флажка до левой границы формы

Расстояние от верхней границы флажка до верхней границы формы

Высоту поля вывода поясняющего текста

Ширину поля вывода поясняющего текста

Шрифт, используемый для отображения поясняющего текста

Признак наследования характеристик шрифта родительской формы

 

Рис. 5.13. Компонент CheckBox

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

Таблица 5.6. Значения свойств компонента CheckBox1

Свойство
Значение
Caption

Checked

Выводить протокол

True

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

При вычислении номера среднего элемента используется функция тгипс, которая округляет до ближайшего целого и преобразует к типу integer выражение, полученное в качестве аргумента. Необходимость использования тгипс объясняется тем, что выражение (niz-verh) /2 — дробного типа, переменная sred — целого, а переменной целого типа присвоить дробное значение нельзя (компилятор выдаст сообщение об ошибке).

Обратите внимание на процедуры обработки события onKeyPress для компонентов stringGridl и Editl. Первая из них обеспечивает перемещение курсора в следующую ячейку таблицы или в поле Editl (из последней ячейки) в результате нажатия клавиши <Enter>, вторая — активизирует командную кнопку Поиск также в результате нажатия клавиши <Enter>.

Листинг 5.8. Бинарный поиск в массиве

unit b_found_;

interface

uses

Windows, Messages, SysUtils, Classes,

Graphics, Controls, Forms, Dialogs, StdCtrls, Grids;

type

TForm1 = class(TForm)

Label1: TLabel;

Label2: TLabel;

Button1: TButton;

Label3: TLabel;

CheckBox1: TCheckBox;

StringGrid1: TStringGrid;

Editl: TEdit;

procedure ButtonlClick(Sender: TObject);

procedure StringGridlKeyPress(Sender: TObject; var Key: Char);

procedure EditlKeyPress(Sender: TObject; var Key: Char); private

{Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

implementation

{$R *.DFM}

{ Бинарным поиск в массиве }

procedure TForm1.Button1Click(Sender: TObject);

const

SIZE=10; var

a:array[1..SIZE] of integer; { массив )

obr:integer; { образец для поиска}

verh:integer; { верхняя граница поиска }

niz: integer; { нижняя граница поиска }

sred:integer; { номер среднего элемента )

found:boolean;{ TRUE — совпадение образца с элементом массива }

n:integer; / число сравнений с образцом }

i:integer;

begin

// ввод массива и образца

for i:=l to SIZE do

a[i]:=StrToInt(StringGridl.Cells[i-l,0] ) ;

obr := StrToInt(Editl.text);

// поиск verh:=1;

niz:=SIZE; n:=0;

found:=FALSE; labels.caption:='';

if CheckBoxl.State = cbChecked

then Labels.caption: ='verh'+#9+'niz'#9'sred' #13;

// бинарный поиск в массиве repeat

sred:=Trunc ( (niz-verh) /2)+verh; if CheckBox1.Checked

then Labels.caption:=label3.caption +IntToStr(yerh) + #9

+IntToStr(niz) + #9 +IntToStr(sred) + #13; n:=n+1;

if a[sred] = obr then found:=TRUE else

if obr < a[sred]

then niz:=sred-1 else verh:=sred+1;

until (verh > niz) or found;

if found

then labels.caption:=label3.caption

+'Совпадение с элементом номер '

+ IntToStr(sred)+#13 + 'Сравнений '

+ IntToStr(n)

else label3.caption:=label3.caption

+'Образец в массиве не найден.';

end;

// нажатие клавиши в ячейке StringGrid

procedure TForml.StringGridlKeyPress(Sender: TObject; var Key: Char),

begin

if Key = #13 then // нажата клавиша <Enter>

if StringGrid1.Col < StringGridl.ColCount - 1

then // курсор в следующую ячейку таблицы

StringGridl.Col := StringGrid1.Col +1

else // курсор в поле Editl, в поле ввода образца

Editl.SetFocus;

end;

// нажатие клавиши в поле Editl

procedure TForm1.Edit1KeyPress(Sender: TObject;. var Key: Char);

begin

if Key = #13 // нажата клавиша <Enter>

then // сделать активной командную кнопку

Button1.SetFocus;

end;

end.

Ниже приведены примеры диалоговых окон программы Бинарный поиск в массиве после выполнения поиска— с выводом протокола (рис. 5.14, а) и без протокола (рис. 5.14, б).

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

а

б

Рис. 5.14. Примеры работы программы бинарного поиска в массиве

Сортировка массива

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

а[1] < а[2] < ...< a[SIZE]

где SIZE — верхняя граница индекса массива.

Примечание

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

Существует много методов (алгоритмов) сортировки массивов.

Рассмотрим два из них:

  • метод прямого выбора;
  • метод прямого обмена.

Сортировка методом прямого выбора

Алгоритм сортировки массива по возрастанию методом прямого выбора может быть представлен так:

1. Просматривая массив от первого элемента, найти минимальный элемент и поместить его на место первого элемента, а первый — на место минимального.

2. Просматривая массив от второго элемента, найти минимальный элемент и поместить его на место второго элемента, а второй — на место минимального.

3. И так далее до предпоследнего элемента.

Ниже представлена программа сортировки массива целых чисел по возрастанию, диалоговое окно которой изображено на рис. 5.15.

Рис. 5.15. Диалоговое окно программы сортировки массива простым выбором

Процедура сортировки, текст которой приведен в листинге 5.9, запускается нажатием кнопки Сортировка (Button1). Значения элементов массива вводятся из ячеек компонента StringGrid1. После выполнения очередного цикла поиска минимального элемента в части массива процедура выводит массив в поле метки (Label2).

Листинг 5.9. Сортировка массива простым выбором

procedure TForm1.ButtonlClick(Sender: TObject);

const

SIZE=10;

var

a:array[1..SIZE] of integer;

min:integer; { номер минимального элемента в части

массива от i до верхней границы массива }

j:integer; { номер элемента, сравниваемого с минимальным }

buf:integer; { буфер, используемый при обмене элементов массива }

i,k:integer;

begin

// ввод массива

for i:=l to SIZE do

a[i]:=StrToInt(StringGridl.Cells[i-1,0]) ; Iabel2.caption:='';

for i:=l to SIZE-1 do begin

{ поиск минимального элемента в части массива от а[1] до a[SIZE]} min:=i;

for j:=i+l to SIZE do if a[j] < a [min]

then min:=j;

{ поменяем местами a [min] и a[i] }

buf:=a[i]; a[i]:=a[min]; a[min]:=buf;

{ вывод массива }

for k:=l to SIZE do

Label2.caption:=label2.caption+' '+IntTostr(a[k]);

Label2.caption:=label2.caption+#13; end;

Label2.caption:=label2.caption+#13+'MaccMB отсортирован.';

end;

На рис. 5.16 приведено диалоговое окно программы после завершения процесса сортировки.

Рис. 5.16. Диалоговое окно программы Сортировка массива

Сортировка методом обмена

В основе алгоритма лежит обмен соседних элементов массива. Каждый элемент массива, начиная с первого, сравнивается со следующим, и если он больше следующего, то элементы меняются местами. Таким образом, элементы с меньшим значением продвигаются к началу массива (всплывают), а элементы с большим значением — к концу массива (тонут). Поэтому данный метод сортировки обменом иногда называют методом "пузырька". Этот процесс повторяется столько раз, сколько элементов в массиве, минус единица.

На рис. 5.17 цифрой 1 обозначено исходное состояние массива и перестановки на первом проходе, цифрой 2 — состояние после перестановок на первом проходе и перестановки на втором проходе, и т. д.

Рис. 5.17. Процесс сортировки массива

Рис. 5.18. Диалоговое окно программы Сортировка методом обмена

На рис. 5.18 приведено диалоговое окно программы сортировки массива методом обмена.

Процедура сортировки, текст которой приведен в листинге 5.10, запускается нажатием кнопки Сортировка (Button1). Значения элементов массива вводятся из ячеек компонента stringGridl. Во время сортировки, после выполнения очередного цикла обменов элементов массива, программа выводит массив в поле метки Label2.

Листинг 5.10. Сортировка массива методом обмена

procedure TForm1.Button1Click(Sender: TObject);

const

SIZE=5;

var

a:array[1..SIZE] of integer;

k:integer; // текущий элемент массива

i:integer; // индекс для ввода и вывода массива

changed:boolean; // TRUE, если в текущем цикле были обмены

buf:integer; // буфер для обмена элементами массива

begin

// ввод массива

for i:=1 to SIZE do

a[i] := StrToInt(StringGrid1.Cells[i-1, 0] );

label2.caption:='';

// сортировка массива repeat

Changed:=FALSE; // пусть в текущем цикле нет обменов

for k:=l to SIZE-1 do

if a[k] > a[k+l] then

begin // обменяем k-й и k+1-й элементы

buf := a[k]; a[k] := a[k+l]; a[k+l] := buf;

changed := TRUE;

end;

// вывод массива

for i:=l to SIZE do

Label2.caption:=label2.caption+' '+IntTostr(a[i]);

Label2.caption:=label2.caption+#13;

until not changed; // если не было обменов, значит

// массив отсортирован

Label2.caption:=label2.caption

+#13+'Maccив отсортирован.';

end;

Следует отметить, что максимальное необходимое количество циклов проверки соседних элементов массива равно количеству элементов массива минус один. Вместе с тем возможно, что массив реально будет упорядочен за меньшее число циклов. Например, последовательность чисел 5 1 2 3 4, если ее рассматривать как представление массива, будет упорядочена за один цикл, и выполнение оставшихся трех циклов не будет иметь смысла.

Поэтому в программу введена логическая переменная changed, которой перед выполнением очередного цикла присваивается значение FALSE. Процесс сортировки (цикл repeat) завершается, если после выполнения очередного цикла проверки соседних элементов массива (цикл for) ни один элемент массива не был обменен с соседним, и, следовательно, массив уже упорядочен.

Рис. 5.19. Пример работы программы сортировки массива методом обмена

На рис. 5.19 приведено диалоговое окно программы сортировки массива методом обмена после завершения процесса сортировки.

Многомерные массивы

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

Таблица 5.7


Январь
Февраль
Март
...
Ноябрь
Декабрь
ВA3 2106






ВA3 2107






ВA3 2108






ВA3 2109






ВАЗ 2110






ВАЗ 2111






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

vaz2106: array [1..12] of integer;

vaz2107: array [1..12] of integer;

vaz2108: array [1..12] of integer;

vaz2109: array [1..12] of integer;

vaz2110: array [1..12] of integer;

vaz2111: array [1..12] of integer;

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

Возможно и такое представление таблицы:

jan: array [1..6] of integer;

feb: array [1..6] of integer;

mar: array [1..6] of integer;

dec: array [1..6] of integer;

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

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

В общем виде инструкция объявления двумерного массива выглядит так:

Имя:array[НижняяГраница1..ВерхняяГраница1,

НижняяГраница2..ВерхняяГраница2] of Тип

где:

  • Имя — имя массива;
  • array — слово языка Delphi, указывающее, что объявляемый элемент данных является массивом;
  • НижняяГраница1, ВерхняяГраница1, НижпяяГраница2, ВерхняяГраница2 — целые константы, определяющие диапазон изменения индексов и, следовательно, число элементов массива;
  • Тип — тип элементов массива.

Табл. 5.7 может быть представлена в виде двумерного массива следующим образом:

itog: array [1..12, 1..6] of integer

Количество элементов двумерного массива можно вычислить по формуле:

(ВГ1-НГ1+1) х (ВГ2-НГ2+1):

где:

  • ВГ1 и ВГ2 — верхняя граница первого и второго индексов;
  • НГ1 и НГ2 — нижняя граница первого и второго индексов. Таким образом, массив itog состоит из 60 элементов типа integer.

Для того чтобы использовать элемент массива, нужно указать имя массива и индексы элемента. Первый индекс обычно соответствует номеру строки таблицы, второй — номеру колонки. Так, элемент itog [2,3] содержит число проданных в марте (третий месяц) автомобилей марки ВАЗ 2107 (данные о продаже ВАЗ 2107 находятся во второй строке таблицы).

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

s := 0;

for j := 1 to 12 do

s := s + itog[2,j];

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

s:=0;

for i := 1 to 6 do // шесть моделей автомобилей

for j := 1 to 12 do //12 месяцев s := s + itog[i,j];

В приведенном фрагменте программы каждый раз, когда внутренний цикл (цикл по j) завершается, во внешнем цикле значение i увеличивается на единицу и внутренний цикл выполняется вновь. Таким образом, к текущему значению переменной s последовательно прибавляются значения элементов массива itog: itog[l,l], itog[l,2], ..., itog[l,12], itog[2,l], itog[2,2], ..., itog[2,12] и т. д.

В качестве примера рассмотрим программу, которая обрабатывает результаты спортивных соревнований летней олимпиады в Сиднее, 2000 г. Исходные данные представлены в табл. 5.8.

Таблица 5.8. Результаты олимпиады 2000 г. в Сиднее

Страна
Золотых
Серебряных
Бронзовых
Австралия
16
25
17
Беларусь
3
3
11
Великобритания
11
10
7
Германия
14
17
26
Италия
13
8
13
Китай
28
16
15
Корея
8
9
11
Куба
11
11
7
Нидерланды
12
9
4
Россия
32
28
28
Румыния
11
6
9
США
39
25
33
Франция
13
14
11
Япония
5
8
5

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

Вид диалогового окна программы приведен на рис. 5.20.

Рис. 5.20. Диалоговое окно программы Итоги олимпиады

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

Таблица 5.9. Значения свойства компонента StringGrid1

Свойство
Значение
Name
Tab1
ColCount
6
RowCount
14
FixedCols
0
FixedRows
1
Options . goEditing
TRUE
DefaultColWidth
65
DefaultRowHeight
14
GridLineWidth
1

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

процедура обработки события OnActivate (ее текст приведен в листинге 5.11), которое происходит во время активизации формы приложения. Кроме того, эта процедура вписывает в первую колонку таблицы названия стран-участниц соревнований.

Листинг 5.11. Инициализация таблицы

procedure TForml.FormActivate(Sender: TObject); begin

tabl.Cells[0,0] ='Страна';

tabl.Cells[1,0] ='Золотых';

tabl.Cells[2,0] ='Серебряных';

tabl.Cells[3,0] ='Бронзовых';

tabl.Cells[4,0] ='Bcero';

tabl.Cells[5,0] ='Баллов';

tabl.Cells[0,1] ='Австралия';

tabl.Cells[0,2] ='Белоруссия';

tabl.Cells[0,3] ='Великобритания';

tabl.Cells[0,4] ='Германия';

tabl.Cells[0,5] ='Италия';

tabl.Cells[0,6] ='Китай';

tabl.Cells[0,7] ='Корея';

tabl.Cells[0,8] ='Куба';

tabl.Cells[0,9] ='Нидерланды';

tabl.Cells[0,10]— 'Россия';

tabl.Cells[0,ll]:='США';

tabl,Cells[0,12]:='Франция';

tabl.Cells[0,13]:='Япония'; end;

Программа обработки исходной таблицы (листинг 5.12) запускается щелчком мыши на командной кнопке Итоги (Buttoni).

Листинг 5.12. Обработка двумерного массива

procedure TForml.ButtonlClick(Sender: TObject);

var

c,r:integer; // номер колонки и строки таблицы

s:integer; // всего медалей у команды

р:integer; // очков у команды

m:integer; // номер строки с максимальным количеством очков

buf:array[0..5] of string; // буфер для обмена строк

i:integer; // номер строки. Используется во время сортировки

begin

for r:=l to tab1.rowcount do // обработать все строки

begin s:=0;

// вычисляем общее кол-во медалей

for c:=l to 3 do

if tabl.cells[c,r] <>''

then s:=s+StrToInt(tab1.cells[c,r])

else tabl.cells[c,r]:='0'; // вычисляем количество очков

p:=7*StrToInt(tab1.cells[l,r])+

6*StrToInt(tabl.cells[2, r] )

+ 5*StrToInt(tabl.cells[3,r]};

// вывод результата

tabl.cells[4,r]:=IntToStr(s); // всего медалей

tabl.cells[5,r]:=IntToStr(p); // очков

end;

// сортировка таблицы по убыванию в соответствии

// с количеством баллов (по содержимому 5-го столбца)

// сортировка методом выбора

for r:=l to tab1.rowcount-1 do

begin

m:=r; // максимальный элемент — в r-й строке

for i:=r to tabl.rowcount-1 do

if StrToInt(tabl.cells[5,i])>StrToInt(tabl.cells[5,m])

then m:=i;

if r <> m then

begin // обменяем г-ю и m-ю строки таблицы

for c:=0 to 5 do begin

buf[с]:=tab1.Cells[c,r];

tab1.Cells[c,r]:=tabl.Cells[c,m];

tab1.Cells[c,m]:=buf[c];

end;

end;

end;

end;

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

На рис. 5.21 приведено диалоговое окно программы после завершения процесса обработки массива.

Рис. 5.21. Окно программы Итоги олимпиады

Ошибки при использовании массивов

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

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

day : array[0..6] of string[ll],

то во время компиляции программы инструкция

day [7] := 'Воскресенье';

будет помечена как ошибочная.

Если для доступа к элементу массива в качестве индекса используется переменная или выражение, то возможно возникновение ошибки (исключения) времени выполнения программы. Например, если в программе объявлен массив

tab1: array [1..N] of integer;

то инструкция

for i:=0 to N do tab1[i] := 5;

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

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

При запуске рассматриваемой программы из Delphi возникает исключение, и сообщение имеет вид, приведенный на рис. 5.22.

Рис. 5.22. Сообщение об ошибке при обращении к несуществующему элементу массива (программа запущена из Delphi)

Если программа запущена из Windows, то при попытке присвоить значение несуществующему элементу массива на экран будет выведено сообщение Range check error (ошибка контроля диапазона). В заголовке окна будет указано имя приложения, в процессе выполнения которого произошла ошибка (рис. 5.23).

Рис. 5.23. Сообщение об ошибке при обращении к несуществующему элементу массива (программа запущена из Windows)

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

Для того чтобы программа контролировала значения индексных выражений (в этом случае Delphi добавляет в выполняемую программу инструкции, обеспечивающие этот контроль), необходимо на вкладке Compiler диалогового окна Project Options, которое открывается выбором из меню Project команды Options, установить флажок Range checking (Контроль диапазона), находящийся в группе Runtime errors (Ошибки времени выполнения) (рис. 5.24).

Рис. 5.24. Вкладка Compiler диалогового окна Project Options

 

<< НазадСодержаниеВперед >>

 

®Сайт разработал: Nek по вопросам пишите сюда NekSuper@yandex.ru
 
Hosted by uCoz