Programming Taskbook 0


Download 1.62 Mb.
Pdf ko'rish
bet60/71
Sana21.06.2023
Hajmi1.62 Mb.
#1644761
TuriУчебное пособие
1   ...   56   57   58   59   60   61   62   63   ...   71
Bog'liq
Abramyan-Pascal2016-1

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


Глава 5. Дополнительные средства обработки массивов 
99 
ми индексами для массива размера N. Для элементов с нечетными индек-
сами формула имеет вид N div 2, а для элементов с четными индексами — 
(N + 1) div 2. При этом число N может быть как четным, так и нечетным. 
5.2.
Изменение размеров динамического массива 
В определении массива, данном в п. 3.1, особо отмечалось, что массив 
размещается на непрерывном участке оперативной памяти. Это условие 
является важным, так как оно обеспечивает быстрое нахождение адреса 
любого элемента массива по его индексу. С другой стороны, отмеченное 
условие, казалось бы, не позволяет изменять размер уже созданного мас-
сива. Действительно, после участка, на котором располагается массив, мо-
гут быть размещены другие данные программы, и поэтому «расширить» 
память для массива (сохраняя ее в виде непрерывного участка) окажется 
невозможно. Это справедливо для статических массивов, которые, будучи 
созданы, сохраняют свой размер на протяжении всей программы. Однако 
для динамических массивов ситуация иная.
Во всех современных реализациях Паскаля предусмотрены средства
позволяющие изменить размер динамического массива (эти средства были 
добавлены в язык одновременно с включением в него динамических мас-
сивов; из распространенных реализаций Паскаля это впервые было сдела-
но в языке Delphi Pascal версии 4). Таким образом, слово «динамический» 
в отношении массивов PascalABC.NET означает не только то, что массив 
можно создать в любой момент выполнения программы, но и то, что в 
дальнейшем его размер можно изменить с сохранением прежнего содер-
жимого.
Для изменения размера массива a достаточно вызвать процедуру 
SetLength(a, newLength), в которой второй параметр определяет новый раз-
мер. В результате переменная a будет связана с массивом нового размера 
(который может быть больше или меньше размера исходного массива), 
причем все сохранившиеся элементы исходного массива сохранят свои 
значения (а новые будут содержать нулевые значения соответствующего 
типа).
Следует, однако, иметь в виду, что операция изменения размера дина-
мического массива является длительной и ресурсоемкой операцией. Она 
требует, во-первых, выделения памяти под новый массив и, во-вторых, ко-
пирования в новый массив сохраняемой части исходного массива.
Заметим, что процедуру SetLength можно вызвать даже для неинициа-
лизированного массива, т. е. сразу после его описания (когда переменная a 
имеет значение nil и, таким образом, не связана с каким-либо конкретным 
массивом, размещенным в памяти). Это означает, что процедуру SetLength 
можно использовать для инициализации массива, как и конструктор new. 
Именно с помощью процедуры SetLength обеспечивается инициализация 


100 
динамических массивов в языке Delphi Pascal, тогда как вариант инициали-
зации с применением конструктора new заимствован языком Pascal-
ABC.NET из языка C#. Вариант с конструктором является более кратким, 
так как не требует предварительного описания массива. Ниже приведены 
два варианта описания и инициализации массивов одинакового размера: 
для массива a1 использован конструктор, для массива a2 — процедура 
SetLength: 
var a1 := new integer[10]; 
var a2: array of integer; 
SetLength(a2, 10); 
Чтобы проиллюстрировать особенности применения процедуры 
SetLength, рассмотрим задачу Array54, в которой требуется переписать в 
новый массив b все четные числа из исходного массива a в том же порядке 
и вывести размер полученного массива и его элементы. Одним из вариан-
тов решения может быть следующий: 
Task('Array54'); // Вариант 1 
var a := ReadArrInteger; 
var b := new integer[0]; 
foreach var e in a do 
if not Odd(e) then 
begin 
SetLength(b, b.Length + 1); 
b[b.Length - 1] := e; 
end; 
b.WriteAll; 
Вначале мы создаем пустой результирующий массив b, а затем в цик-
ле, как только в исходном массиве обнаруживается четное число, увеличи-
ваем размер массива b и добавляем это число в конец увеличенного масси-
ва. Для вывода как размера массива, так и его элементов мы использовали 
специальный метод вывода WriteAll, предусмотренный в задачнике. Заме-
тим, что создать пустой массив целого типа можно было бы и с помощью
функции-генератора ArrFill(0, 0). 
Это решение дает правильный результат и выглядит достаточно при-
влекательно. Однако многократные вызовы процедуры SetLength при обра-
ботке массивов большого размера могут существенно замедлить выполне-
ние этого алгоритма. Для того чтобы это продемонстрировать, будем гене-
рировать большие массивы случайных чисел (используя функцию ArrRan-
dom — см. п. 3.3), применять к ним описанный алгоритм и замерять время 
его работы. Время генерации исходного массива не будем учитывать, не 
будем также выводить на печать полученный массив: 
var size := 10000; 


Download 1.62 Mb.

Do'stlaringiz bilan baham:
1   ...   56   57   58   59   60   61   62   63   ...   71




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling