Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
uchebnaya_praktika.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
107.01 Кб
Скачать
    1. Краткие теоретические сведения

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

В отличие от таких статических переменных в программах, написанных на языке Pascal, могут быть созданы динамические переменные. Основное свойство динамических переменных заключается в том, что они создаются и память для них выделяется во время выполнения программы. Размещаются динамические переменные в динамической области памяти (heap - области).

Динамическая переменная не указывается явно в описаниях переменных и к ней нельзя обратиться по имени. Доступ к таким переменным осуществляется с помощью указателей.

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

Множество значений переменной-указателя состоит из адресов ячеек памяти и специального значения NIL, которое ни на что не указывает. NIL не является реальным адресом, а означает отсутствие ссылки на какой-либо объект. Не путайте со случаем, когда значение указателя не определено, NIL – вполне определенное значение.

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

Работа с динамической областью памяти в Pascal реализуется с помощью процедур New и Dispose.

Процедура New(p) выделяет место в динамической области памяти для размещения динамической переменной p^ и ее адрес присваивает указателю p.

Процедура Dispose(p) освобождает участок памяти, выделенный для размещения динамической переменной процедурой New, и значение указателя p становится неопределенным.

Порядок работы с динамической переменной:

– создать (отвести для нее место в динамической памяти;

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

– удалить (освободить занятое этой переменной место).

Приведенный ниже пример покажет работу с динамическими переменными и указателями:

var p1,p2:^real; {описание указателей на динамическую переменную типа real (конкретный тип нужен для определения размера)}

...

New(p1); {создать динамическую переменную и присвоить указателю p1 значение ее адреса}

p1^:=3.1415; {заполнение динамической переменной}

p2:=p1; {теперь указатель p2 показывает на ту же переменную}

writeln(p2^); {можно в этом убедиться, распечатав ее значение}

dispose(p1); {удалить переменную, освободив динамическую память}

    1. Пример программы

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

Аношенко Г. 4.0

Ракаускайте К. 3.0

Терентьев М. 3.1

Хардин К. 4.0

Гончаренко С. 5.0

Требуется:

  1. создать массив указателей на записи, содержащие сведения о студентах;

  2. написать процедуру вывода информации о студентах на экран;

  3. написать процедуру, определяющую студентов с наибольшей и наименьшей оценкой и меняющую их местами.

В приведенной ниже программе задачу 2 выполняет процедура Screen, задачу 3 – процедура Change.

Рассмотрим программу. В начале основной программы массив указателей GrpPtr заполняется значениями nil.

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

Рисунок 4.1 – До выполнения процедуры Change

В процедуре Change выявляются номер указателя на запись с наибольшим значением поля Ball (переменная imax) и номер указателя на запись с наименьшим значением поля Ball (переменная imin). Далее в указатель с номером imax записывается адрес, который хранился в указателе с номером imin. А в указатель с номером imin помещается адрес, ранее хранившийся в элементе массива с номером imax (см. рисунок 4.2).

Рисунок 4.2 – После выполнения процедуры Change

Вызов процедуры Screen по окончании работы процедуры Change выведет данные в виде:

Аношенко Г. 4.0

Гончаренко С. 5.0

Терентьев М. 3.1

Хардин К. 4.0

Ракаускайте К. 3.0

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

Текст программы имеет следующий вид.

program practic;

const NMAX=30;

type tStudent = record {запись}

Surname: String[20];

Ball : Real;

end;

pStudent = ^tStudent; {указатель на запись}

tGroup = array[1..NMAX] of pStudent; {массив указателей}

var GrpPtr: tGroup;

f: Text;

i: Integer;

fname: String[30];

{**************процедура вывода на экран**********************}

procedure Screen(var gr: tGroup);

var i: integer;

begin

writeln('*******gruppa*******');

i:=1;

while gr[i]<>nil do

begin

writeln(gr[i]^.Surname, gr[i]^.Ball:3:1);

i:=i+1;

end;

end;

{*************процедура обмена местами студентов ****************

*******************с высшим и низшим баллами*********}

procedure Change(var gr: tGroup);

var imax, imin, i: integer;

min, max : real;

ptmp : pStudent; {указатели}

begin

i := 1; imin := 1; imax := 1;

min := gr[1]^.Ball; max := gr[1]^.Ball;

{poisk max i min elementa}

while gr[i] <> nil do

begin

if gr[i]^.Ball > max then

begin

max := gr[i]^.Ball;

imax := i;

end;

if gr[i]^.Ball < min then

begin

min := gr[i]^.Ball;

imin := i;

end;

i:=i+1;

end;

{обмен указателей на данные с минимальным и максимальным значением поля Ball}

{меняем местами не сами записи a их адреса!}

ptmp := gr[imax];

gr[imax] := gr[imin];

gr[imin] := ptmp;

end;

{***************основная программа*****************}

begin

{заполняем массив указателей значениями nil}

for i:=1 to NMAX do

GrpPtr[i]:=nil;

{чтение данных из файла}

write('Enter file name ');

readln(fname);

assign(f,fname);

reset(f);

i:=1;

while not eof(f) do

begin

new(GrpPtr[i]); {выделяем память под новую динамическую переменную и помещаем ее адрес в i-ый элемент массива указателей}

with GrpPtr[i]^ do {помещаем данные в динамическую переменную}

readln(f,Surname, Ball);

i:=i+1;

end;

close(f);

{границу используемой части массива указателей теперь отмечает элемент,

содержащий значение nil}

Screen(GrpPtr); {Вывод данных на экран}

readln;

Change(GrpPtr); {Обмен}

Screen(GrpPtr); {Вывод данных на экран}

readln;

{удаление динамических переменных из памяти}

i:=1;

while GrpPtr[i]<>nil do

begin

dispose(GrpPtr[i]);

i:=i+1;

end;

end.

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