Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка DELPHI.DOC
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.73 Mб
Скачать

Динамические массивы

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

Var V = array of real; VI = array of integer;

Каждая из объявленных переменных (V или VI) может иметь значение какого-то адреса. Прежде чем располагать данные, этот адрес переменная должна получить. Память под данные выделяется процедурой SetLength: SetLength(V,5);

SetLength(VI,10);

В данном случае объявлено 5 элементов одномерного массива вещественных чисел V и 10 элементов массива целых чисел VI. Нужное количество памяти выделится процедурой SetLength, эта же процедура присвоит конкретные значения адресов переменным V и VI.

Имеются особенности в использовании динамических массивов. Первая – нумерация индекса всегда начинается с нуля. Вторая особенность касается правил присваивания, например, пусть объявлено: Type Vekt = array of real; Var V1,V2:Vekt; Присваивание V1:=V2; для статических массивов означает, что содержимое памяти V1 заменяется содержимым памяти V2 (элементы массива V1 получили значения элементов V2). Если учесть, что в данном случае V1 и V2 являются ссылками (адресами), поэтому адрес V1 заменяется на адрес V2. Таким образом, для динамических массивов присваивание V1:=V2; означает, что V1 и V2 ссылаются теперь на один и тот же участок памяти, т.е. элементы массива V1 равны элементам V2, но потерялся адрес V1, соответственно потерялся и выделенный участок памяти, начиная с адреса V1. Освободить память, выделенную под V1 можно, вызвав перед операцией присваивания V1:=V2; процедуру Finalize: Finalize(V1); или просто, присвоив V1:=nil;.

Динамические массивы могут быть и многомерными, например, объявив Var VV:array of array of real;. Далее в программе можно задать размерности массива SetLength(VV,5,10);

Динамические массивы позволяют, например, создавать треугольные матрицы, имеющие различные размерности индексов. Интерес к таким массивам в вычислительной математике очень большой. Для создания таких массивов сначала нужно задать размерность по первому индексу, например для объявленного выше двумерного массива VV так: SetLength(VV,3);. Это означает, что массив будет состоять из 3 строк. Теперь длину каждой строки зададим отдельно:

SetLength(VV[0],1); SetLength(VV[1],2);

SetLength(VV[2],3);

Если требуется освободить память из-под такого массива, то используется один вызов процедуры Finalize или одно присваивание VV:=nil;

Начальный и конечный индексы динамического одномерного массива V можно определять функциями Low(V) (равно 0) и High(V), как, например, в следующем операторе

For i:=Low(V) to High(V) do . . . ;

Пример 8

Задан одномерный массив чисел X = (0,2; 0,7; 1,8; 3,1; 4,2). Получить таблицу косинусов для этих чисел, т.е. рассчитать cos(0,2), cos(0,7), ... cos(4,2). На рис. 23 представлен вариант решения этого примера.

Рис. 23 Форма с вариантом решения примера 8.

Для решения задачи был использован новый компонент TStringGrid (таблица строк), который находится на странице Additional палитры компонентов. Данный компонент представляет собой двумерную таблицу строк. Количество строк задается свойством RowCount, а количество столбцов - ColCount. Размеры одной ячейки таблицы на экране задаются свойствами DefaultColHeight и DefaultRowWidth в пикселах. Компонент может использоваться для имитации чего-либо похожего на таблицу. Доступ к отдельной ячейке таблицы осуществляется с помощью свойства Cells[i,j], где i-номер столбца, j-номер строки. Отсчет номеров столбца и строки начинается с нуля. Часть строк и столбцов, используемых в таблице, можно зафиксировать. Тогда они будут недоступны пользователю. Для этого нужно задать свойство FixedRows и FixedCols (фиксированное количество строк и столбцов). Фиксированные колонки и строки закрашиваются в другой цвет. Используются они для заголовков. С помощью свойства goEdit можно запретить или разрешить редактирование ячеек таблицы.

В данном примере для StringGrid1 установлено: ScrollBars = ssNone, RowCount = 6, ColCount = 3, FixedRows = 1, FixedCols = 1, GoEdit = false. Ниже приводится программа решения данного примера 8.

unit prim8;

interface

uses Windows, Messages, SysUtils,Classes,

Graphics, Controls, Forms, Dialogs,

StdCtrls, Buttons, ExtCtrls, Grids;

type

TForm1 = class(TForm)

Panel1: TPanel;

Button1: TButton;

BitBtn1: TBitBtn;

StringGrid1: TStringGrid;

procedure Button1Click(Sender: TObject);

end;

var Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);

const n=5;

x:array [1..n] of real =(0.2,0.7,1.8,3.1,4.2);

var i:integer;

begin

for i:=1 to n do

StringGrid1.Cells[0,i]:=IntToStr(i)+' элемент';

StringGrid1.Cells[1,0]:=' x';

StringGrid1.Cells[2,0]:=' cos(x)';

for i:=1 to n do begin

StringGrid1.Cells[1,i]:=

FormatFloat(' 0.0',x[i]);

StringGrid1.Cells[2,i]:=

FormatFloat(' 0.0000',cos(x[i]));

end;

end;

end.

СТРОКИ

В Delphi существует 5 типов строк:

  • ShortString – короткая строка;

  • AnsiString – длинная строка;

  • WideString – длинная строка в кодировке UNICODE;

  • String – универсальная строка;

  • PChar – строка, оканчивающаяся нулевым кодом (#0), введена для совместимости с другими языками программирования (такие строки используются в С++ и Windows).

Переменная PChar – это ссылка на строку. Строки типа PChar размещаются в динамической памяти. Динамическая память – это свободная память, которая остается после загрузки программ и данных. Программный элемент получает её в процессе выполнения программы, а не на этапе компиляции (статическая память). Переменная типа PChar – это ячейка памяти, содержащая адрес строки. По этому адресу записываются необходимые данные. Компилятор выделяет под переменную PChar всего 4 байта, а сама строка, которая размещается по адресу, записанному в эти 4 байта, может быть любой длины. Если строки не существует, а переменная PChar объявлена, то в эту переменную необходимо записать nil (пустой адрес).

Переменные типа AnsiString содержат динамические строки символов в ANSI кодировке. Соответственно переменные типа WideString содержат динамические строки символов в кодировке UNICODE. Динамические – это означает, что переменные указанных типов, как и тип PChar, являются адресами, т.е. ссылками на память с соответствующим типом данных.

ShortString – это фактически массив: array [0..255] of char.Память в данном случае выделяется в 256 байт, а строка размещается динамически, т.е. через адрес. Символы строки содержатся в байтах с первого по 255. В байте с номером 0 содержится символ, порядковый номер которого представляет собой число фактически имеющихся в строке символов. Данный тип ShortString введён для совместимости с более ранними версиями языка Pascal.

Строка String в зависимости от директивы компилятора {$Н} может совпадать с AnsiString ({$H+} установлено по умолчанию), или с ShortString({$H-}).

Для строки String можно задавать максимальное количество символов с помощью следующего объявления: var str: String[25];, т.е. строка str может содержать не более 25 символов и в памяти она занимает 26 байт (не считая “накладные расходы”).

Доступ к строке может осуществляться посимвольно, так как все символы в строке проиндексированы. В строке PChar символы нумеруются, начиная с 0, в остальных строках, - начиная с 1. Например, пусть объявлено:

Var str1: String; str2: PChar; и выполнены присваивания: str1:=’Pascal’; str2:= ’Pascal’; - тогда str[1] представляет символ P, а str2[1] – символ a.

Со строками возможны операции конкатенации (сложения) и сравнения. Складываются строки, используя знак ‘+’. При сравнении строк действия выполняются слева направо в соответствии с ANSI кодами отдельных символов. Например код А меньше чем а. Если строки разной длины, то короткая строка дополняется справа, причем код, который участвует в дополнении строки, меньше кода любого символа, существующего в ANSI кодировке.

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

Таблица 11

Некоторые операции со строками.

Операция

Описание

Copy(S, pos, len)

Возвращает подстроку длиной len символов из строки S, начиная с символа номер pos.

Length(S)

Возвращает фактическую (динамическую) длину строки S.

Pos(substr, S)

Возвращает позицию первого вхождения подстроки substr в строку S.

SetLength(S, newlen)

Задаёт новую длину newlen строке S.

StringOfChar(Ch, Count)

Возвращает строку, заполненную символом Ch в количестве Count.

Trim(S)

Возвращает строку без начальных и конечных пробелов.

UpperCase(S)

Возвращает строку с прописными буквами.

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