Главная   страница 1 ... страница 3страница 4страница 5страница 6


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

Существуют два процедурных типа: тип-процедура и тип-функция. Описание процедурного типа имеет вид:

type <�имя процедурного типа> =

<�заголовок процедуры или функции без имени>;

Например:

type funcl = function (a, b : real) : real;

Процедурные типы широко применяются в Object Pascal при использовании классов.




1.5 Динамическая память и указатели

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

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

Любая ячейка оперативной памяти – байт – имеет собственный адрес (номер). Адреса переменных можно хранить в переменных специального типа – указателях. Указатели могут быть типизированными и нетипизированными.

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

var <�имя указателя> : ^ <�тип> ;

Например,

var p1, p2 : ^integer; p3 : ^real;

Здесь p1 и p2 – указатели на переменные типа integer, а p3 – указатель на переменную типа real.

Указателю может быть присвоено пустое значение nil , например p1:=nil, означающее, что переменная p1 ни на что не указывает, т.е. не содержит адрес какой-либо ячейки памяти. Как правило, при запуске программы все указатели содержат значение nil.

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

p1:=p2;


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

p1^:=p1^+2;

Адрес любой переменной можно получить с помощью операции взятия адреса @. Например, если L – переменная типа integer, то допустим следующий оператор:

p1:=@L;


Для работы с динамическими переменными в программе должны быть предусмотрены:

 выделение памяти под динамическую переменную;

 присвоение указателю адреса выделенной памяти (инициализация указателя);

 освобождение памяти после использования динамической переменной.

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

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

var x: pointer;

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

procedure GetMem(var p:pointer; size:integer);

Резервирует фрагмент динамической памяти требуемого размера size, в переменной p сохраняется адрес начала этого фрагмента.

procedure FreeMem(var p:pointer[; size:integer]);

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




1.6 Массивы

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



Статические массивы

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

type <�имя типа>=array[<�тип индекса (индексов)>] of <�тип компонентов>;

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

Например:

type vector = array[1..3] of real;

table = array[1..4] of array[1..5] of integer;

Здесь vector – одномерный массив, состоящий из трёх вещественных чисел, table – двумерный массив (матрица), состоящий из четырёх строк и пяти столбцов целых чисел. Описание типа table можно также записать следующим образом:

type table = array[1..4, 1..5] of integer;

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

Для описанных выше типов можно задать, например, следующие переменные:

var m1, m2 : vector; matr : table;

Массив можно описать и непосредственно в разделе описания переменных:

var m1, m2 : array[1..3] of real;

matr : array[1..4, 1..5] of integer;

В Object Pascal одним оператором присваивания можно передать все элементы одного массива другому массиву того же типа, например:

m1:=m2;

Однако, объявление



var a : array[1..6] of integer;

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

создаст разные типы массивов, поэтому оператор a:=b вызовет ошибку.

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

m1[2] matr[3,4] m2[i+1]

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

procedure S(a : array[1..10] of integer);

Правильно будет сначала описать тип массива в разделе type основной программы. Например:

const n = 10;

type lin = array[1..n] of integer;

procedure S(a : lin);

……………………………….



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

const n = 10;

type lin = array[1..n] of integer;

Заполнение массива числами, введёнными с клавиатуры:

procedure init1(var x : lin);

var i : integer;

begin

for i:=1 to n do read(x[i]);



end;

Заполнение массива случайными числами с помощью генератора случайных чисел:

procedure init2(var x:lin);

var i:integer;

begin

randomize;



for i:=1 to n do x[i]:=-50 + random(101);

end;


Функция random(t) берёт случайное целое число из отрезка [0, t-1]. Таким образом, массив будет заполнен случайными числами от -50 до 50.

Распечатка массива (вывод элементов массива на экран)

procedure print(x : lin);

var i : integer;

begin

for i:=1 to n do write(x[i]:4);



writeln

end;
Пример 29. Заполнить массив случайными числами от -25 до 25. Распечатать массив. Заменить отрицательные элементы массива на противоположные по знаку. Распечатать преобразованный массив.

const n = 10;

type lin = array[1..n] of integer;

var a : lin;

procedure init2(var x : lin);

var i : integer;

begin


randomize;

for i:=1 to n do x[i]:=-25 + random(51);

end;

procedure print(x : lin);



var i : integer;

begin


for i:=1 to n do write(x[i]:4);

writeln


end;

procedure sign1(var x : lin);

var i : integer;

begin


for i:=1 to n do

if x[i]<0 then x[i]:=-x[i]

end;

begin


init2(a); print(a);

sign1(a); print(a);

readln

end.


Задачи.

103. Заполнить массив случайными числами от -30 до 30. Распечатать массив.

1) Найти сумму положительных элементов.

function sum_pol(x:lin):integer;

2) Подсчитать количество чётных элементов.

function kol_chet(x:lin):integer;

3) Напечатать номера нечётных элементов.

procedure nechet(x:lin);

4) Если элемент является чётным числом, то прибавить к нему первый элемент массива, в противном случае – последний элемент массива. Первый и последний элементы массива не изменять.

procedure solve1(var x:lin);

5) Заменить элементы с k1-ого по k2-ой на противоположные по знаку.

procedure solve2(var x:lin; k1, k2:integer);

6) Сформировать массив b, каждый элемент которого равен

b[i]=a[1] + a[2] + … +a[i].

procedure solve3(x:lin; var y:lin);

7) Все элементы массива, предшествующие последнему отрицательному элементу массива, умножить на 10.

function last_neg(x:lin):integer;

procedure solve4( var x:lin);

104. Заполнить одномерный целочисленный массив размерности 10 элементами геометрической прогрессии, первый элемент которой равен а, знаменатель прогрессии – d.

procedure init_geom(var q:lin; a, d:integer),

105. Заполнить одномерный целочисленный массив размерности 20 числами Фибоначчи.

procedure init_fib(var x:lin);

106. Даны действительные числа a1, a2, … , an (n=10). Получить числа b1, b2, … , bn (n=10) , где bi – среднее арифметическое всех элементов последовательности a1, a2, … , an , кроме ai (i=1, 2,…,n).

107. Даны действительные числа a1, a2, … , an, b1, b2, … , bn (n=10). Вычислить (a1 + bn)(a2 + bn-1) … (an + b1).



Максимум и минимум одномерного массива.

Пример 30. Найти максимальный элемент целочисленного массива размерности n.

const n = 10;

type lin = array[1..n] of integer;

var a : lin; res : integer;

procedure init1(var x : lin);

var i : integer;

begin

for i:=1 to n do read(x[i]);



end;

function max(x : lin) : integer;

var i : integer;

begin


result:=x[1];

for i:=2 to n do

if x[i]>result then result:=x[i]

end;


begin

init1(a);

res:=max(a); writeln(res);

readln; readln

end.
Задачи.

108. Найти номер максимального элемента одномерного целочисленного массива размерности 10.

109. Даны целые числа a1, a2, … , a10 . Заменить элемент последовательности нулём, если ai  max(a1, a2, … , a10 ), и единицей в противном случае.

110. Даны целые числа a1, a2, … , a10 . Все элементы этой последовательности, предшествующие первому по порядку элементу со значением max(a1, a2, … , a10 ) домножить на max(a1, a2, … , a10 ).

111. Дана последовательность действительных чисел a1,…,a10 . Требуется домножить все элементы этой последовательности на квадрат её минимума, если a10, и на квадрат её максимума, если a10.

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

113*. Дано вещественное число a и вещественный массив из n элементов. Среди элементов массива найти два таких элемента b и c (если они существуют), что числа a, b, c могут быть сторонами прямоугольного треугольника с максимальной площадью. Вывести длины сторон этого треугольника и его площадь.

114*. Даны координаты n точек на плоскости (x1,y1), (x2,y2),…, (xn,yn) . Найти номера двух точек, расстояние между которыми наибольшее. (Считать, что такая пара точек единственная).



Удаление, вставка, перестановка элементов одномерного массива.

Пример 31. В одномерном целочисленном массиве размерности n удалить элемент с номером k.

Решение. Удаление элемента будет осуществлять процедура del(kk:byte; var m:lin). Её работа заключается в том, что все элементы, начиная с номера kk+1, и до номера n сдвигаются на один влево. Например, для удаления 5ого элемента массива

11 3 -8 6 23 -17 9 31 4 15

нужно осуществить сдвиг:




11 3 -8 6 23 -17 9 31 4 15


const n = 10;

type lin = array[1..n] of integer;

var a : lin; k : byte;

procedure init1(var x : lin);

var i : byte;

begin


for i:=1 to n do read(x[i])

end;


procedure del(kk : byte; var x : lin);

var i : byte;

begin

for i:=kk to n-1 do x[i]:=x[i+1];



x[n]:=0

end;


procedure print1(nn : byte; x : lin);

var i : byte;

begin

for i:=1 to nn do write(x[i]:5);



writeln

end;


begin

init1(a);

readln(k); del(k, a);

print1(n-1, a);

readln

end.


После введения последовательности чисел

11 3 -8 6 23 -17 9 31 4 15

и номера удаляемого элемента 5 на экран будет выведен преобразованный массив:

11 3 -8 6 -17 9 31 4 15


Пример 32. В одномерном целочисленном массиве размерности n вставить целое число x после элемента с номером k.

Решение. Вставку числа x после элемента с номером k будет осуществлять процедура ins(kk:byte; xx:integer; var x:lin). Её работа заключается в том, что все элементы, начиная с номера kk, и до номера n сдвигаются на один вправо (начиная с конца массива). Например, для вставки числа 100 после 5ого элемента массива

11 3 -8 6 23 -17 9 31 4 15

нужно осуществить сдвиг:




11 3 -8 6 23 -17 9 31 4 15

Затем поставить число 100 на место элемента с номером kk+1

11 3 -8 6 23 100 -17 9 31 4 15

Полученный массив будет содержать n+1 элемент, поэтому массив сразу должен быть описан, как массив размерности n+1.

const n=10;

type lin=array[1..n+1] of integer;

var a:lin; k:byte; r:integer;

procedure init1(var x:lin);

var i:byte;

begin

for i:=1 to n do read(x[i])



end;

procedure ins(kk:byte; rr:integer; var x:lin);

var i:byte;

begin


for i:=n downto kk+1 do x[i+1]:=x[i];

x[kk+1]:=rr

end;

procedure print1(nn:byte; x:lin);



var i:byte;

begin


for i:=1 to nn do write(x[i]:5);

writeln


end;

begin


init1(a);

readln(k, r); ins(k, r, a);

print1(n+1, a);

readln


end.
Пример 33. В одномерном целочисленном массиве размерности n поменять местами первую и вторую половины массива.

Решение. Алгоритм заключается в том, что 1ый элемент меняется местами с последним, 2ой элемент – с предпоследним и так далее. Процедура swap(k1, k2:byte; var m:lin); меняет местами два элемента с номерами k1 и k2.

const n=10;

type lin=array[1..n] of integer;

var a:lin; j:byte;

procedure init1(var x:lin);

var i:byte;

begin


for i:=1 to n do read(x[i])

end;


procedure swap(k1, k2:byte; var x:lin);

var d:integer;

begin d:=x[k1]; x[k1]:=x[k2]; x[k2]:=d end;

procedure print(x:lin);

var i:byte;

begin


for i:=1 to n do write(x[i]:5);

writeln


end;

begin


init1(a);

for j:=1 to n div 2 do swap(j, n – j + 1, a);

print(a);

readln; readln

end.

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

Для решения многих задач необходимо упорядочить данные по определённому признаку. Процесс упорядочения заданного множества объектов по определённому признаку называется сортировкой. Элементы массива можно сортировать по возрастанию a[1]<�…a[2]>…>a[n], по невозрастанию a[1]a[2]…a[n]. Научившись выполнять одну сортировку, изменить её, чтобы получить другую, не составляет особого труда.



Пример 34. Сортировка простого обмена (пузырьком).

Рассмотрим идею метода на примере. Отсортируем по возрастанию массив из 5 элементов 5 11 9 4 3. Будем просматривать пары рядом стоящих элементов массива и, если элементы стоят неправильно, то менять их местами.

1ый просмотр. 5 11 9 4 3 ( 5 < 11 не меняем)

5 11  9 4 3 ( 11 > 9 меняем)

5 9 11  4 3 ( 11 > 4 меняем)

5 9 4 11  3 ( 11 > 3 меняем)

Элемент 11 теперь находится на своём месте.

2ой просмотр. 5 9 4 3 11 ( 5 < 9 не меняем)

5 9  4 3 11 ( 9 > 4 меняем)

5 4 9  3 11 ( 9 > 3 меняем)

Элемент 9 теперь находится на своём месте.

3ий просмотр. 5  4 3 9 11 ( 5 > 4 меняем)

4 5  3 9 11 ( 5 > 3 меняем)

Элемент 5 теперь находится на своём месте.

4ый просмотр. 4  3 5 9 11 ( 4 > 3 меняем)

Элементы 3 и 4 теперь находятся на своих местах.

Процедура сортировки.

procedure sort(var x:lin);

var k, i, w:integer;

begin


for k:=1 to n-1 do

for i:=1 to n-k do

if x[i] > x[i+1] then

begin w:=x[i]; x[i]:=x[i+1]; x[i+1]:=w end;

end;

Таким образом, мы произвели n-1 просмотр массива, на каждом k-ом просмотре выполняется n-k сравнений. Массив отсортирован. Этот метод называют также методом пузырька, так как в процессе сортировки элементы с заданным свойством постепенно всплывают на поверхность.


Пример 35. Сортировка простыми вставками.

На i-ом шаге сортировки считается, что часть массива, содержащая первые i-1 элементов уже упорядочена, то есть a[1]< …

Рассмотрим этот процесс на примере. Пусть требуется отсортировать массив из пяти элементов 13 6 8 11 3 по возрастанию.

1ый шаг. 13 6 8 11 3

2ой шаг. 6 13 8 11 3

3ий шаг. 6 8 13 11 3

4ый шаг. 6 8 11 13 3

5ый шаг. 3 6 8 11 13


Процедура сортировки.

procedure sort(var x:lin);

var i, j, w:integer;

begin


for i:=2 to n do

begin


w:=x[i]; j:=i-1;

while (j>0) and (w

begin x[j+1]:=x[j]; dec(j) end;

x[j+1]:=w

end;

end;
Задачи.



115. Удалить из одномерного целочисленного массива размерности n первый отрицательный элемент.

116. Удалить из одномерного целочисленного массива размерности n последний чётный элемент.

117*. Удалить из одномерного целочисленного массива размерности n все отрицательные элементы.

118. Вставить число x после первого отрицательного элемента.

119. Вставить число x перед последним отрицательным элементом.

120. Дана последовательность различных действительных чисел a1,…,a10 . Поменять местами максимальный элемент и последний элемент последовательности.

121. Дана последовательность различных действительных чисел a1,…,a10 . Поменять местами минимальный элемент и первый отрицательный элемент последовательности.

122. В одномерном целочисленном массиве размерности n (n=10) поменять местами первую и вторую половины массива.

a1, a2, … a5, a6, … a9, a10  a6, … a9, a10, a1, a2, … a5

123. Дан одномерный целочисленный массив размерности n (n=10). Переставить его элементы следующим образом: поменять местами первые три и последние три элемента, сохраняя порядок их следования.

124*. Дан одномерный целочисленный массив размерности n (n=10). Переставить в обратном порядке элементы массива, расположенные между минимальным и максимальным элементами.


Двумерные массивы. Инициализация. Работа с элементами.

Пример 36. Заполнить двумерный массив размера nm (n строк, m столбцов) целыми числами, введёнными с клавиатуры. Ко всем отрицательным элементам массива прибавить первый элемент соответствующей строки. Вывести преобразованный массив на экран.

const n=4; m=5;

type lin = array[1..m] of integer;

mas = array[1..n] of lin;

var a:mas;

procedure init1_mas(var x:mas);

var i,j:integer;

begin


for i:=1 to n do for j:=1 to m do read(x[i,j])

end;


procedure print_mas(x:mas);

var i,j:integer;

begin

for i:=1 to n do



begin

for j:=1 to m do write(x[i,j]:6);

writeln

end


end;

procedure solve(var x:mas);

var i,j:integer;

begin


for i:=1 to n do

for j:=1 to m do if x[i,j]<0 then x[i,j]:=x[i,j] + x[i,1]

end;

begin


init1_mas(a);

solve(a); print_mas(a);

readln; readln;

end.
Пример 37. Заполнить двумерный массив размера nm (n строк, m столбцов) случайными действительными числами из интервала [-4, 4]. К элементам k1-ой строки прибавить соответствующие элементы k2-ой строки (k1=2, k2=3).

const n=4; m=5;

type lin = array[1..m] of real;

mas = array[1..n] of lin;

var a,b:mas;

procedure init2_mas(var x:mas);

var i,j:integer;

begin

randomize;



for i:=1 to n do for j:=1 to m do x[i,j]:=(-40 + random(81))/10;

end;


procedure print_mas(x:mas);

var i,j:integer;

begin

for i:=1 to n do



begin for j:=1 to m do write(x[i,j]:6:1); writeln end;

writeln;


end;

procedure sum_str(var x:mas; k1, k2:integer);

var j:integer;

begin


for j:=1 to m do x[k1,j]:=x[k1,j]+x[k2,j];

end;


begin

init2_mas(a); print_mas(a);

b:=a; sum_str(b, 2, 3); print_mas(b);

readln;


end.
Пример 38. Заполнить квадратную матрицу размера nn следующим образом:

const n=8;

type mas = array[1..n,1..n] of integer;

var a:mas;

procedure fill(var x:mas);

var i,j:integer;

begin

for i:=1 to n do for j:=1 to n do



if j=n–i+1 then x[i,j]:=i else x[i,j]:=0

end;


procedure print_mas(x:mas);

var i,j:integer;

begin

for i:=1 to n do



begin for j:=1 to n do write(x[i,j]:6); writeln; writeln end;

end;


begin

fill(a); print_mas(a);

readln;

end.
Пример 39. Дан двумерный целочисленный массив размера nm. Напечатать номера строк, все элементы которых чётны.



const n=4; m=5;

type lin = array[1..m] of integer;

mas = array[1..n] of lin;

var a:mas; k:integer;

procedure init1_mas(var x:mas);

var i,j:integer;

begin

for i:=1 to n do for j:=1 to m do read(x[i,j])



end;

function control(y:lin):boolean;

var j:integer; t:boolean;

begin


t:=true; j:=1;

while (j<=m) and t do

begin t:=not odd(y[j]); inc(j) end;

result:=t

end;

begin


init1_mas(a);

for k:=1 to n do

if control(a[k]) then writeln(k);

readln; readln

end.
Пример 40. Дан двумерный целочисленный массив размера nm. Сформировать одномерный массив, каждый элемент которого равен сумме элементов соответствующей строки исходного массива. Вывести полученный одномерный массив на экран. Найти номер строки с максимальной суммой элементов.

const n=4; m=5;

type lin = array[1..m] of integer;

mas = array[1..n] of lin;

vector = array[1..n] of integer;

var a:mas; rez:vector; nmax:integer;

procedure init1_mas(var x:mas);

var i,j:integer;

begin

for i:=1 to n do for j:=1 to m do read(x[i,j])



end;

procedure print(x:vector);

var k:integer;

begin


for k:=1 to n do write(x[k]:5);

writeln


end;

procedure sum_str(x:mas; var z:vector);

var i,j,s:integer;

begin


for i:=1 to n do

begin


z[i]:=0;

for j:=1 to m do z[i]:=z[i] + x[i,j]

end;

end;


function max_sum(z:vector):integer;

var k, max:integer;

begin

max:=z[1]; result:=1;



for k:=2 to n do

if max

begin max:=z[k]; result:=k end;

end;


begin

init1_mas(a);

sum_str(a, rez); print(rez);

nmax:=max_sum(rez); writeln(nmax);

readln; readln;

end.
Пример 41. Найти произведение двух квадратных матриц размера nn.

const n=4;

type mas = array[1..n, 1..n] of integer;

var a, b, c:mas;

procedure init1_mas(var x:mas);

var i,j:integer;

begin


for i:=1 to n do for j:=1 to n do read(x[i,j])

end;


procedure print_mas(x:mas);

var i,j:integer;

begin

for i:=1 to n do



begin

for j:=1 to n do write(x[i,j]:6); writeln

end

end;


procedure mult(x,y:mas; var z:mas);

var i, j, k:integer;

begin

for i:=1 to n do for j:=1 to n do



begin

z[i,j]:=0;

for k:=1 to n do z[i,j]:=z[i,j] + x[i,k]*y[k,j]

end


end;

begin


init1_mas(a);

init1_mas(b);

mult(a, b, c);

print_mas(c);

readln; readln;

end.
Задачи.

125. Заполнить двумерный массив размера nm (n строк, m столбцов) действительными числами, введёнными с клавиатуры. (Все элементы матрицы различны, среди них есть и положительные, и отрицательные числа).

1) Найти сумму элементов матрицы.

2) Найти количество отрицательных элементов матрицы.

3) Найти максимальный элемент матрицы и его индексы.

4) Найти среднее арифметическое положительных элементов матрицы.

5) Все элементы матрицы, сумма индексов которых кратна 3, заменить нулями.

6) Получить новую матрицу путём деления всех элементов матрицы на её наибольший по модулю элемент.

7) Найти сумму элементов строки, в которой расположен элемент с наименьшим значением.

8*) Найти максимальный среди отрицательных элементов матрицы.

126. Заполнить двумерный массив размера nn (n=5) случайными целыми числами из интервала [-60, 60]. Получить квадратный массив того же порядка, в котором элемент равен единице, если соответствующий элемент исходного массива больше элемента, расположенного в его строке на главной диагонали, и равен нулю в противном случае.

127. Заполнить массив 66 следующим образом:

1 2 3 4 5 6

2 1 2 3 4 5

3 3 1 2 3 4

4 4 4 1 2 3

5 5 5 5 1 2

6 6 6 6 6 1


128*. Заполнить массив 55 следующим образом:

1 -2 3 -4 5

-10 9 -8 7 -6

11 -12 13 -14 15

-20 19 -18 17 -16

21 -22 23 -24 25
129. Дан двумерный целочисленный массив размера nm. Сформировать одномерный массив, каждый элемент которого равен количеству чётных элементов соответствующей строки исходного массива. Вывести полученный одномерный массив на экран. Найти номер строки с максимальным количеством чётных элементов.

130. Дан двумерный целочисленный массив размера nm. Сформировать одномерный массив, каждый элемент которого равен максимальному элементу соответствующей строки исходного массива. Вывести полученный одномерный массив на экран. Найти номер строки с минимальным среди максимальных элементов строк.

131. Дан двумерный целочисленный массив размера nm. Напечатать номера строк

1) все элементы которых одинаковы;

2) элементы которых образуют симметричные последовательности;

3) элементы которых образуют возрастающие последовательности.

132. Дана квадратная матрица A размера nn (n=4). Найти A2 + A3.

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

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

Объявить динамический массив можно следующим образом:

var <�имя масива> : array of <�тип>;

Например:

var vect : array of real;

Длину массива следует задать при помощи процедуры SetLength. Например:

SetLength(vect, 6);

Данная процедура выделяет для массива vect в оперативной памяти место для 6 вещественных элементов и присваивает этим элементам нулевые значения. Индекс первого элемента равен 0, поэтому массив vect содержит элементы vect[0], vect[1],…, vect[5]. При желании длину динамического массива можно изменить при помощи повторного использования процедуры SetLength. Если новая длина окажется больше исходной, то в массив добавляются новые элементы с нулевыми значениями; если меньше, то последние элементы в исходном массиве будут отброшены.

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

1. Присвоить переменной значение nil, например:

vect:=nil;

2. Использовать процедуру finalize, например:

finalize(vect);

3. Установить нулевую длину, например:

SetLength(vect, 0);

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

…………………………………….

var r : array of array of integer;

…………………………………….

SetLength(r, 3);

SetLength(r[0], 1);

SetLength(r[1], 2);

SetLength(r[2], 3);

……………………………………..

создаёт треугольный массив.



Параметры-массивы

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

procedure T(x : array[1..10] of real);

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

Если в подпрограмму передаётся массив, то следует первоначально описать его тип, например:

type tmas = array[1..10] of real;

procedure T(x : tmas);

…………………………………..

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

procedure Q(t : array of real; var w : array of array of real);

Начальное значение индекса в открытом массиве равно 0, как и в динамическом. В подпрограмме реальная длина массива может быть определена либо при помощи функции Length – длина массива, либо при помощи функции High – наибольшее значение индекса. Для этих функций справедливо следующее соотношение:

High(<�массив>) = Length(<�массив>) – 1.

В качестве фактического параметра для открытого массива может выступать и статический массив.

Пример 42. Заполнить случайными целыми числами из интервала [-20,20] двумерный целочисленный массив размера nm, где n – случайное число из интервала [2, 5], m=n+1. В каждой строке массива вставить число, равное i100 ( i – номер строки), после третьего элемента.

type matrix = array of array of integer;

var a : matrix;

n, m, i, j : integer;

procedure init_dinmas(var x:matrix);

var i, j:integer;

begin

for i:=0 to n-1 do



for j:=0 to m-1 do x[i,j]:=-20 + random(41);

end;


procedure print_dinmas(x:matrix; nn, mm:integer);

var i,j:integer;

begin

for i:=0 to nn-1 do



begin for j:=0 to mm-1 do write(x[i,j]:5); writeln end;

end;


begin

randomize;

n:=random(4)+2; m:=n+1;

setlength(a, n, m); writeln(n:5, m:5);

init_dinmas(a); print_dinmas(a, n, m);

setlength(a, n, m+1);

for i:=0 to n-1 do

begin


for j:=m-1 downto 3 do a[i, j+1]:=a[i, j];

a[i, 3]:=(i+1)*100;

end;

print_dinmas(a, n, m+1);



readln

end.
Пример возможного варианта выполнения программы:

3 4

-4 -7 7 19



10 -2 5 7

6 -14 6 -3

-4 -7 7 100 19

10 -2 5 200 7

6 -14 6 300 -3

1.7 Строки

Строковые типы

Строка представляет собой набор символов, заключённый в апострофы. Например:  abcdef   Иванов И.И.   10.0   S = 

Константа типа char представляет собой символьную строку единичной длины. Используемые в Object Pascal строковые типы приведены в следующей таблице:


Тип строки

Максимальная длина


Нулевой символ в конце

ShortString

255 байт

Нет

AnsiString

2 Гб

Есть

String

255 байт / 2 Гб

Нет / Есть

WideString

1 Гб

Есть

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

Например, для строки st , имеющей тип shortstring и значение st =  Object  , получим:

ord(st[0])=6, st[1]=O, st[2]=b, st[3]=j, st[4]=e, st[5]=c, st[6]=t.

Длина строки, хранящаяся в нулевом байте, представлена в символьном виде, поэтому для преобразования в число следует воспользоваться стандартной функцией ord, а обратно – функцией chr.

Короткая строка размещается компилятором в памяти компьютера до начала выполнения программы, т.е. статически.

Строка типа AnsiString располагается в памяти иначе. Сама переменная типа AnsiString занимает в памяти 4 байта и является указателем, т.е. содержит адрес той ячейки памяти, начиная с которой будет фактически располагаться символьная строка. Выделение места в памяти происходит на этапе выполнения программы, т.е. динамически. Программа сама определяет необходимую длину строки по заданному количеству символов, и операционная система выделяет нужный участок памяти. В конце строки размещается терминальный (завершающий ) нуль – символ #0 и так называемый счётчик ссылок, занимающий 4 байта. Счётчик ссылок позволяет экономить память. Например, если в программе имеется фрагмент:
……………………………………

var s1, s2 : ansistring;

……………………………………

s1 stroka ;

s2  s1;

…………………………………..

то память для размещения переменной s2 не выделяется, а в переменную s2 помещается значение указателя из переменной s1. Счётчик ссылок в области памяти, связанной с переменной s1, увеличивает своё значение на 1 и станет равным 2. В программе может быть несколько переменных, ссылающихся на одну и ту же строку. Счётчик ссылок равняется количеству ссылающихся на строку переменных. Если одна из ссылающихся на строку типа AnsiString переменных изменит своё значение, то в памяти будет выделено место для новой строки. Число ссылок в прежней строке уменьшится на 1, а в новой строке становится равным 1. Если число ссылок на строку станет равным 0, то строка уничтожается и освобождает место в памяти. Нумерация символов в строке типа AnsiString начинается с 1. Процедура SetLength, которую мы использовали для установления длины динамического массива, может быть также использована для установления длины строки типа AnsiString.

Тип String интерпретируется компилятором Object Pascal по-разному, в зависимости от значения директивы компилятора $H. Если она включена – {$H+} – то тип String интерпретируется как AnsiString, если нет – {$H-} – то как ShortString. По умолчанию действует директива {$H+}.

Если в разделе описаний указано, например String[10], то независимо от директив компилятора тип трактуется как ShortString с указанным числом символов.

Тип WideString также представляет собой динамически размещаемые в памяти компьютера строки, длина которых ограничена только объёмом свободной памяти компьютера. Однако в отличие от строки типа AnsiString каждый символ является Unicode-символом, т.е. кодируется 2 байтами.



Пример 43. В строке Ivanov I. дописать полностью имя (Ivan).

var s : ansistring;

begin

s:='Ivanov I.';



setlength(s, 12);

s[9]:='v'; s[10]:='a'; s[11]:='n'; s[12]:='.';

writeln(s);

readln;


end.

Стандартные подпрограммы для строк.

function AnsiCompareStr(const S1, S2 : string): integer;

Сравнивает две строки S1 и S2 в кодировке Ansi с учётом регистра. Возвращает значение меньше 0, если S1S2. В русифицированных версиях Widows может быть применена к строкам, содержащим русские буквы.

function AnsiCompareText(const S1, S2 : string): integer;

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

function AnsiLowerCase(const S : string): string;

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

function AnsiPos(const Substr, S : string): integer;

Возвращает позицию (индекс) первого вхождения Substr в S. Если Substr не входит в S, то возвращается 0. В русифицированных версиях Windows может быть применена к строкам, содержащим русские буквы.

function AnsiUpperCase(const S : string): string;

Возвращает строку S в кодировке Ansi, преобразованную к верхнему регистру. В русифицированных версиях Windows может быть применена к строкам, содержащим русские буквы.

function Concat(S1, S2…SN : string): string;

Возвращает строку, представляющую сцепление строк S1, S2… SN. Идентична операции + для строк.

function Copy(S; Index, Count: integer): string;

Параметр S – это строка типа string или динамический массив. Функция Copy возвращает подстроку строки S, начинающуюся с символа с номером Index и содержащую Count символов.

procedure Delete(var S : string; Index, Count : integer);

Удаляет из S подстроку, начинающуюся с символа с номером Index и содержащую Count символов.

procedure Insert(Substr : string; S : string; Index : integer);

Вставляет строку Substr в S, начиная с символа с номером Index.

function Length(S : string): integer;

Возвращает число символов в строке S.

function Pos(Substr, S : string): integer;

Возвращает позицию (индекс) первого вхождения подстроки Substr в строку S. Если Substr нет в S, то возвращается 0.

procedure SetLength(var S; NewLength : integer);

Параметр S является строкой или динамическим массивом. Процедура устанавливает новую длину NewLength строки S. Если строка имеет тип ShortString, то значение параметра NewLength должно находиться в диапазоне 0..255. Для длинных строк значение параметра NewLength ограничено лишь размерами доступной памяти компьютера. При увеличении длины строки старые значения, находившиеся там, сохраняются, а во вновь добавленных позициях находятся неопределённые значения.

function StringOfChar(Ch : char; Count : integer): string;

Создаёт строку, состоящую из Count раз повторяющегося символа Ch.

function Trim(const S : string): string;

Удаляет из строки S начальные и завершающие пробелы и управляющие символы.

Строковые выражения

Над строками определены операции отношения. Строки сравниваются по кодам символов. Напомним, что для консольных приложений используется кодировка ASCII, а для оконных – ANSI. При сравнении двух строк последовательно сравниваются коды символов, стоящих в одинаковых позициях. Символы в строках просматриваются слева направо. Если в очередной паре оказываются различные символы, то большей считается та строка, символ которой имеет больший код. На этом сравнение прекращается. Если сравниваются строки разной длины, причём одна строка совпадает с началом другой, то большей будет более длинная строка.

Например,

муха < слон

слон < слоник

2 > 123

Кроме операций отношения над строками определена операция сцепления (конкатенации), которая обозначается знаком + . Например,

Object +  Pascal = Object Pascal

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

Для ввода символьных строк необходимо использовать процедуру readln, а не read. Это объясняется тем, что в конце каждой символьной строки, вводимой с клавиатуры, стоит так называемый разделитель строк EOLN (end of line) – последовательность кодов #13(CR – перевод каретки) и #10(LF – переход на начало строки). Разделитель строк вставляется во вводимый текст при нажатии на клавишу Enter. Процедура readln считывает все символы, расположенные до разделителя строк, а затем и символы разделителя строк (#13 и #10), которые являются управляющими и переводят курсор дисплея в начало следующей строки.



Пример 44. Используя стандартные функции для строк, получить из строки 'grammofon' строку fonogramma.

var t, s : string; i, j : integer; Комментарий

begin

s:='grammofon';



i:=pos('o', s); i = 6

t:=copy(s, 1, i-1); t = gramm

delete(s, 1, i); s = fon

j:=length(s); j = 3

s:= s + t + 'a'; s = fongramma

insert('o', s, j+1); s = fonogramma

writeln(s); readln

end.
Пример 45. Дана строка s, введённая с клавиатуры. Определить, сколько раз входят в строку английские малые гласные буквы.

var s, v : string;

function glas(w:string; st:string) : byte;

var i:byte;

begin


result:=0;

for i:=1 to length(st) do

if pos(st[i], w)<>0 then inc(result)

end;


begin

v:='aeiouy'; readln(s);

writeln(glas(v, s));

readln


end.
Пример 46. Дана строка s, содержащая не более 20 символов. Удалить все буквы  z  .

Приведём текст функции, удаляющей из строки s все буквы  z  .

function solve(st:string):string;

begin


while pos('z', st)<>0 do

begin


delete(st, pos('z', st), 1)

end;


result:=st

end;
Пример 47. Дана строка s. Сформировать строку, состоящую из всех различных строчных английских букв, встречающихся в строке s.

var s, v : string;

function engl(w:string; st:string) : string;

var k, i : byte;

begin


result:='';

for i:=1 to length(st) do

if (pos(st[i], w)<>0) and (pos(st[i], result)=0)

then result:=result + st[i]

end;

begin


v:='abcdefghijklmnopqrstuvwxyz'; readln(s);

writeln(engl(v, s));

readln

end.
Пример 48. Дана строка, содержащая не более 40 символов, являющихся строчными английскими буквами и запятыми. Последний символ – точка. Последовательность букв между двумя соседними знаками препинания назовём словом. Напечатать в столбец по одному все слова из 4 букв.



type slovo = array[1..40] of string;

var s:string; st:slovo; j, n:byte;

procedure spisok(ss:string; var sp:slovo; var k:byte);

var i:byte;

begin

k:=1;


while pos(' , ', ss)<>0 do

begin


i:=pos(' , ', ss);

sp[k]:=copy(ss, 1, i-1); delete(ss, 1, i);

inc(k);

end;


sp[k]:=copy(ss, 1, length(ss)-1)

end;


begin

readln(s);

spisok(s, st, n);

for j:=1 to n do if length(st[j])=4 then writeln(st[j]);

readln

end.
Задачи.



133. Известно, что в строке S есть только одна запятая. Не используя операторы цикла, преобразовать строку S следующим образом: поменять местами части строки S, стоящие до и после запятой.

134. Известно, что в строке S встречается сначала один символ  # , а потом один символ   . Не используя операторы цикла, преобразовать строку S следующим образом: часть строки S, расположенную между этими символами, перенести в начало строки S.

135. Из строки S удалить среднюю букву, если длина строки нечётная, иначе удалить две средние буквы.

136. Дана строка S, введённая с клавиатуры. Если последний символ строки – точка, то удалить из строки все запятые. В противном случае оставить строку без изменения.

137. Дана строка S, введённая с клавиатуры. Удалить из строки S все предыдущие вхождения последнего символа.

138. Дана строка S, введённая с клавиатуры. Заменить каждую букву z буквой f.

139. Дана строка S, введённая с клавиатуры. После каждой буквы z вставить букву f.

140. Дана строка S, введённая с клавиатуры. Удвоить каждое вхождение в строку буквы  t .

141. Дана строка S, введённая с клавиатуры. Сформировать строку, состоящую из всех цифр, встречающихся в строке S.

142. Дана строка S, введённая с клавиатуры. Сформировать строку, состоящую из всех знаков препинания ( ? ! , . : ; ), встречающихся в строке S.

143. Дана строка S, введённая с клавиатуры. Если в ней нет символа    , то оставить строку без изменения, иначе каждую из малых латинских букв, предшествующих первому вхождению символа   , заменить на цифру  3 .

144. Дана строка S, введённая с клавиатуры. Если в ней нет символа  +  , то оставить строку без изменения, иначе каждую из цифр, предшествующих первому вхождению символа  + , заменить на символ  # .

145. Даны три строки S1, S2, S3. Сформировать строку, в которую входили бы в алфавитном порядке по одному разу общие английские буквы трёх данных строк.

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

147*. Дана строка, содержащая текст, состоящий только из малых английских букв и пробелов. Зашифровать этот текст следующим образом: каждую букву заменить на букву, стоящую на d (d < 26) позиций правее в алфавите. Расшифровать зашифрованный текст. (Считать, что алфавит склеен по кругу: после буквы  z  идёт буква  a .)

148. Дана строка, содержащая не более 40 символов, являющихся строчными латинскими буквами и запятыми. Последний символ – точка. Последовательность букв между двумя соседними знаками препинания назовём словом. Напечатать в столбец по одному:



  1. Все слова.

  2. Все слова, отличные от последнего.

  3. Слова, которые начинаются и заканчиваются одной и той же буквой.

  4. Ту же последовательность слов, но в обратном порядке.

  5. Все слова, меняя местами в каждом слове первую и последнюю буквы.

  6. Все слова, не содержащие сочетание букв th.

  7. Все слова, в которых менее 5 букв.

  8. Все слова, заменив в каждом слове первую букву заглавной.

  9. Слова, имеющие максимальную в данной последовательности длину.

10*) Симметричные слова.

11*) Ту же последовательность слов в алфавитном порядке.



Преобразование строк в числовые типы и обратно.

Задача преобразования строк в числовые типы и обратно для консольных приложений не актуальна, так как процедуры read, readln, write, writeln выполняют эти преобразования автоматически. Основная область применения этих подпрограмм – оконные приложения, при создании которых программист сам должен предусматривать преобразование типов.

procedure Str(x; var s:string);

Преобразует целое или действительное значение x в строку s (параметр x может иметь указание формата вывода).

procedure Val(s:string; var v; var code:integer);

Преобразует строку s в целую или вещественную переменную v. Параметр code равен нулю, если преобразование прошло успешно, в противном случае он равен номер позиции в строке s, где обнаружен ошибочный символ. Например: если s:='95'; , то в результате выполнения val(s,x,d); x = 95, d=0. Если s=a4, то x=0, d=1.

function StrToInt(s:string):integer;

Возвращает целое число, изображением которого является строка s.

function StrToFloat(s:string):extended;

Возвращает вещественное число, изображением которого является строка s.

function IntToStr(n:integer):string;

Возвращает строку, являющуюся изображением целого числа n.

function FloatToStr(n:extended):string;

Возвращает строку, являющуюся изображением вещественного числа n.

function FloatToStrF(n:extended; format; k, m:integer):string; – строка, являющаяся изображением вещественного n в различных форматах;

при вызове функции указываются:

format – формат (способ изображения);

k – общее количество цифр;

m – количество цифр после десятичной точки.

Значениями параметра format могут быть следующие константы:

ffFixed – число представляется в формате с фиксированной десятичной точкой.

ffExponent – научный формат (экспоненциальная форма записи).

ffGeneral – общий цифровой формат.

ffNumber – аналогичен ffFixed, но в изображении числа используется разделитель групп разрядов.

ffCurrency – денежный формат.

Например: если x=3.587 и s:=floattostrf(x, ffFixed, 7, 3); , то s = 3,587 (используется десятичная запятая).




1.8 Множества

Множественный тип представляет собой конечный набор значений некоторого базового типа. В качестве базового типа может использоваться любой порядковый тип, кроме word, integer, longint, int64.

Описание множественного типа имеет вид:

<�имя типа > = set of <�базовый тип>;

Например:

type mn1 = set of A . . Z;

mn2 = set of 1 . . 5;

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

Пример.


type digitChar  set of 0 .. 9;

digit  set of 0 .. 9;

var s1, s2 : digitChar; s3, s4, s5 : digit;

begin


s1[1, 2, 3]; s2[3, 2, 1];

s3[0..3, 6]; s4[4, 5]; s5[3..9]

end.

[] – пустое множество. Над множествами определены операции:



 – пересечение множеств.

s3s4=[]; s3s5=[3, 6];

 – объединение множеств.

s3+s4=[0 .. 6];

– – разность множеств.

s5 – s4=[3, 6 .. 9];

= – проверка эквивалентности множеств, возвращает true, если множества эквивалентны.

s1=s2


<> – проверка неэквивалентности.

<= – проверка вложения.

s4<=s5 результат true.



in – проверка принадлежности.

7 in s5 результат true.

Стандартные процедуры для работы с множествами:

include(s, i) – включает элемент i базового типа в множество s.

exclude(s, i) – исключает элемент i из множества s.

Использование множеств позволяет сделать программы более эффективными за счёт уменьшения количества различных проверок.



Пример 49. Используя метод Решето Эратосфена напечатать все простые числа из диапазона 1..30.

Суть метода – вычёркиваем из исходного множества [1..30] те числа, которые не являются простыми.

var n : set of 1..30; k, s : integer;

begin


n:=[1..30];

for s:=2 to 15 do

if s in n then

for k:=s+1 to 30 do

if k mod s=0 then exclude(n, k);

for s:=1 to 30 do

if s in n then write(s:3);

readln


end.

Программа работает следующим образом. Вначале s=2. Это значение принадлежит n, поэтому, начиная с числа 3, вычёркиваем все числа, кратные 2. Теперь s=3. Это значение принадлежит n, поэтому, начиная с числа 4, вычёркиваем все числа, кратные 3. Теперь s=4. Это значение уже вычеркнуто из n. Переходим к s=5 и так далее. Вывод на экран элементов полученного множества осуществляем следующим образом: перебираем все элементы базового множества и отбираем для печати те из них, которые принадлежат n.



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

16 17 18 19 20 21 22 23 24 25 26 27 28 29 30


Задачи.

149. Дана непустая последовательность символов. Построить и напечатать множество, элементами которого являются встречающиеся в последовательности:

1) Цифры и знаки арифметических операций.

2) Заглавные латинские буквы от  E  до  T  и знаки препинания (, . ; : ! ?).

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

151*. Составить программу для решения ребуса ИКС + ИСК = КСИ.

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

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

Описание типа запись:

имя типа  record список полей end;

Здесь имя типа – правильный идентификатор. Список полей представляет собой последовательность разделов записи, между которыми ставится точка с запятой. Каждый раздел записи состоит из одного или нескольких идентификаторов полей, отделённых друг от друга запятыми. За идентификатором ставится двоеточие и описание типа поля.

Пример. Запись в телефонной книге может быть представлена в виде следующей структуры данных:

type tel = record

number : integer;

fio : string[40];

adr : string[60]

end;

var m, v : tel;



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

m.number; m.fio; m.adr;

Поля записи используются в программе как обычные переменные соответствующего типа. Например, можно написать

m.numberm.number  1; или m.fio[1]<>Ф

Допускается применение оператора присваивания к записи в целом. Например, vm; После выполнения этого оператора значения полей записи v станут равны значениям соответствующих полей записи m. Логические операции сравнения для записей не определены. Тип запись нельзя использовать для описания типа функции.

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

with переменная типа запись do оператор;

Один раз указав переменную типа запись в операторе with , можно далее работать с именами полей без указания перед идентификатором поля имени записи. Например:

with m do begin number1364; fioПетров end;

Пример 50. Описать тип point для точки на плоскости со следующими полями: буква, обозначающая точку, координата x, координата y. Даны две точки. Найти длину отрезка, соединяющего эти две точки.

type point = record

name : 'A' .. 'Z';

x : real;

y : real

end;


var a, b : point; ab : real;

begin


readln(a.name, a.x, a.y);

with b do

readln(name, x, y);

ab:=sqrt(sqr(b.x – a.x) + sqr(b.y – a.y));

writeln(a.name, b.name, ' = ', ab:5:2); readln

end.
Пример 51. Имеется ведомость n учащихся с оценками за год по информатике. Создать массив из n элементов типа запись с двумя полями: фамилия и оценка. Напечатать фамилии учеников имеющих оценку 4.

const n = 5;

type inf = record

f : string[8];

m : byte


end;

var g : array[1..n] of inf; i:byte;

begin

for i:=1 to n do readln(g[i].f, g[i].m);



for i:=1 to n do with g[i] do

if m=4 then writeln(f);

readln

end.


Задачи.

152. Имеется ведомость n учащихся с оценками за год по информатике. Создать массив из n элементов типа запись с двумя полями: фамилия и оценка.

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

2) Подсчитать средний балл в группе и напечатать фамилии учеников, у которых оценка выше среднего балла.

153. Пусть имеется описание типа

type time = record

h : 0..23;

m, s : 0..59

end;

и переменная ct, имеющая тип time, описывающая данный момент времени (часы, минуты, секунды). Определить значение переменной nt, описывающей момент времени, который наступит через 1 секунду после момента ct. (Тип TDateTime не использовать).



154*. Пусть имеется описание типа

type year = 1900..2010;

month = 1..12;

day = 1..31;

data = record

y : year;

m : month;

d : day


end;

Определить дату следующего дня. (Учесть смену месяцев, смену года, високосные года. Тип TDateTime не использовать.)


Литература.
1. Кандзюба С.П., Громов В.Н. Delphi 5. Базы данных и приложения. Лекции и упражнения. – К.: ДиаСофт, 2001. – 592 с.

2. Окулов С.М. Основы программирования. – М.: БИНОМ. Лаборатория знаний, 2004. – 424 с.: ил.

3. Фаронов В.В. Система программирования Delphi. – СПб. : БХВ –Петербург, 2004. – 912 с.: ил.

Оглавление

1.1 Основные понятия……………………………………………. 3

1.2 Простые типы…………………………………………………. 8

1.3 Операторы……………………………………………………… 16

1.4 Процедуры и функции………………………………………… 31

1.5 Динамическая память и указатели…………………………. 38

1.6 Массивы………………………………………………………… 40

1.7 Строки………………………………………………………….. 58

1.8 Множества…………………………………………………….. 66

1.9 Записи…………………………………………………………. 68



Литература………………………………………………………… 70


</0></0>


<< предыдущая страница  
Смотрите также:
Delphi это среда разработки программ, ориентированных на работу в операционной системе Windows
804.07kb.
Интегрированная среда программирования
716.96kb.
Внимание: Если у Вас установлена ос windows 98 Second Edition
27.8kb.
Основаны на операционной системе Microsoft Windows Mobile 0®, которая поддерживает быструю отправку электронной почты беспроводным путем для связи с корпоративными сетями в реальном времени
58.85kb.
Библиотечный модуль печати налоговых документов с двухмерным штриховым кодом pdf417 Версия 9
34.15kb.
Отформатировать многоуровневый список
15.68kb.
«Основные навыки работы в операционной системе mac os»
123.79kb.
1. Цели освоения дисциплины Дать необходимые знания по основам объектно-ориентированного программирования и разработке приложений в среде Windows
151.84kb.
Современные технологии и экологические проблемы современности
209.84kb.
Безопасность
83.83kb.
Применение параллельных программ в научных исследованиях и образовании
58.03kb.
На сегодняшний момент операционная система Windows фирмы Microsoft во всех ее проявлениях, бесспорно, считается самой распространенной операционной системой на пк: в мире более 150 млн
220.42kb.