Программа по формированию навыков безопасного поведения на дорогах и улицах «Добрая дорога детства» 2





Скачать 127.11 Kb.
НазваниеПрограмма по формированию навыков безопасного поведения на дорогах и улицах «Добрая дорога детства» 2
Дата публикации12.11.2013
Размер127.11 Kb.
ТипКонспект
100-bal.ru > Военное дело > Конспект

Конспект по теме: «Указатели и динамические переменные»

Учитель информатики Батракова Л.В.


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

  • образовывать объекты;

  • выделять для них память;

  • размер данных может превышать 64 килобайта;

  • уничтожать, когда в них исчезает необходимость.


Определение: Динамические переменные - это переменные, память под которые выделяется во время выполнения программы.
Для получения ясного представления о динамических переменных надо рассмотреть структуру памяти во время выполнения программы на языке Паскаль:





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

Сам указатель располагается в статической памяти.





Ссылочная переменная Динамическая переменная

(указатель)

Каждый указатель размещается в сегменте данных или в стеке (если он объявлен в подпрограмме) и занимает там 4 байта (2 слова: номер сегмента и смещение *). Это дополнительные “накладные расходы’ памяти. Поэтому обычные переменные очень редко создают и уничтожают динамически, оставляя эту возможность для больших совокупностей данных. Чем больше размер динамической переменной, тем меньше доля накладных расходов. Например, при хранении в динамической памяти массивов больших размеров лишние 4 байта, затраченные на указатель, несущественны.
*Пояснение: Адресуемое пространство памяти организовано сегментами: последовательными блоками памяти по 64 Кб каждый. Если известен сегмент, то дальнейшее уточнение места объекта в памяти происходит по смещению, т.е. номеру байта от начала сегмента. Любая ячейка памяти определяется парой чисел сегмент: смещение.

Описание ссылочной переменной (указателя)

Формат описания ссылочного типа данных:

Type <тип указателя> = ^ <идентификатор базового типа>,

то есть указатель связан с некоторым типом данных. Такие указатели называются типизированными.

Базовый тип может быть любым, кроме файлового.

Пример описания переменных ссылочного типа:

Type

DinMas=array[1..10000] of real;
  p1=^integer;
  p2=^real;

P3=^DinMas;

Var
  A,B,C:p1;
  X,Y,Z:p2;

M:p3;
  P:^char;

T:^integer;

Cсылочные переменные A, B, C,T указывают на динамические объекты целого типа, X,Y,Z - вещественного, P – символьного, а M - на массив. Значением ссылочной переменной является адрес в динамически выделенной памяти, где хранится объект этого типа.

Однако в Турбо Паскале можно объявлять указатель и не связывать его с конкретным типом данных. Такой указатель называется нетипизированным. Для его объявления служит стандартный тип pointer. Структура и тип таких данных могут меняться во время выполнения программы.

Для обращения к ссылочной переменной используют запись “ A^ ”, что означает: ”идти по адресу, хранящемуся в A”.
Рассмотрим на примере отличие ссылочной переменной от статической.

Пусть дано описание:
Var J:^integer;

I:integer;
После выполнения операций:

J

^:=15;

I:=15;


Операции, определенные над ссылочной переменной (указателем)


  1. Операция присваивания

    1. Ссылочной переменной может быть присвоено “пустое” значение адреса, обозначенное служебным словом nil, что означает, что ссылочная переменная не указывает ни на один динамический объект. Nil — это зарезервированная константа. Значение nil - это два нулевых слова. Оно может быть присвоено указателю любого типа.

p:=nil;


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

p:=q;


    1. Ссылочной переменной может быть присвоен адрес любой переменной

p:=@x; p:= addr(х);

В языке Pascal есть специальная операция получения указателя на переменную (или процедуру) — она обозначается как @. Имеется также эквивалентная ей функция addr.

  1. Операции сравнения (=, <>)

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

Рассмотрим пример. Пусть в программе описаны следующие указатели:

Var q, p: ^Integer;

Если: p:=Nil; q:= Nil; то условие p=q будет истинным.

Можно указатели использовать в условных операторах:

if p=q then… или if p=nil then... {проверка указателя на пустоту}
Процедуры и функции, определенные над ссылочными переменными:


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

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

  3. Проуедура GetMem( var p: Pointer; size: Word ) - выделяет участок памяти в heap - области, присваивает адрес его начала указателю p, размер участка в байтах задается параметром size.

  4. Процедура FreeMem( var p: Pointer ) - освобождает участок памяти, адрес начала которого определен указателем p. Значение указателя p становится неопределенным.

  5. Процедура Mark( var p: Pointer ) - записывает в указатель p адрес начала участка свободной динамической памяти на момент ее вызова.

  6. Процедура Release( var p: Pointer ) - освобождает участок динамической памяти, начиная с адреса, записанного в указатель p процедурой Mark, то есть, очищает ту динамическую память, которая была занята после вызова процедуры Mark.

  7. Функция MaxAvail: Longint - возвращает длину в байтах самого длинного свободного участка динамической памяти.

  8. Функция MemAvail: Longint - полный объем свободной динамической памяти в байтах.

  9. Вспомогательная функция SizeOf( X ): Word - возвращает объем в байтах, занимаемый X, причем X может быть либо именем переменной любого типа, либо именем типа.


Внимание! В PascalABC используются только первые четыре процедуры (new, Dispose, Getmem, Freemem).
При работе с указателями обязательны два этапа:

  1. объявление указателя;

  2. формирование динамических данных, память под которые отводится во время выполнения программы при помощи процедуры New.


Динамические переменные

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

New(P); Р - указатель.

Данный вызов выполняет два следующих действия:

•обращается к операционной системе для выделения области памяти, необходимой для размещения переменной базового типа;

•устанавливает начальный адрес этой области памяти в качестве значения переменной-указателя.
Вызов New можно выполнять в любом месте программы любое число раз, в том числе – циклически. Это позволяет при выполнении программы динамически создавать любое необходимое число переменных базового типа.

После выделения области памяти в неё можно записать необходимое значение, используя ссылочную переменную и символ ^ после ее имени – это называется операцией разыменования.
Определение: Разыменованием ссылки называется получение объекта, на который указывает эта ссылка.
Комбинация имени переменной-указателя и символа ^ превращает указатель в переменную базового типа.

С такой переменной можно выполнять все те операции, которые разрешены для базового типа. Например:

Type Mas1 = Array[1..100] Of Integer;

Var P1 : ^Integer;

P2 : ^String;

Pm : ^Mas1;

Здесь P1 — указатель на динамическую величину целого типа; P2 — указатель на динамическую величину строкового типа; Pm — указатель на динамический массив, тип которого задан в разделе Type.

Память под динамическую величину, связанную с указателем, выделяется в результате выполнения стандартной процедуры NEW:

NEW(P1); NEW(P2); NEW(Pm);

После их выполнения в динамической памяти оказывается выделенным место под три величины (две скалярные и один массив), которые имеют идентификаторы:

P1^, P2^, Pm^

Дальнейшая работа с динамическими переменными происходит точно так же, как со статическими переменными соответствующих типов. Им можно присваивать значения, их можно использовать в качестве операндов в выражениях, параметров подпрограмм и пр. Например, если переменной P1^ нужно присвоить число 25, переменной P2^ присвоить значение символа "Write", а массив Pm^ заполнить по порядку целыми числами от 1 до 100, то это делается так:

P1^:= 25;

P2^:= 'Write';

For I:= 1 To 100 Do Pm^[I]:= I;
Надо понимать разницу между ссылочной переменной (переменной –указатель) и динамической переменной. Покажем это на примере:

Var p,q:^integer;

……

new(p); new (q);

p^:=3; q^:=58;




p:=q;





q:=nil;




Если вместо оператора p:=q написать оператор p^:=q^ , то изменится значение динамической переменной, на которую указывает указатель p.




Если динамическая величина теряет свой указатель, то она становится "мусором".

В программировании под этим словом понимают информацию, которая занимает память, но уже не нужна.

В рассмотренном выше примере, динамическая величина, равная 3, потеряла свой указатель и стала недоступной. Однако место в памяти она занимает. Это и есть пример возникновения "мусора". На схеме показано, что произошло в результате выполнения оператора p := q.

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

DISPOSE(<указатель>);

Например, если динамическая переменная p^ больше не нужна, то оператор DISPOSE(P)

удалит ее из памяти. После этого значение указателя p становится неопределенным (НЕ путать с ПУСТЫМ указателем!) и ее нельзя использовать до тех пор, пока она снова не будет инициализирована с помощью вызова New или инструкции присваивания.

Особенно существенным становится эффект экономии памяти при удалении больших массивов.
Внимание! Распределение и освобождение памяти для нетипизированных указателей (pointer) производится с помощью специальных стандартных функций GetMem и FreeMem.
Рассмотрим предыдущий пример с использованием процедуры DISPOSE(P):

Var p,q:^integer;

……

new(p); new (q);

p^:=3; q^:=58;




despose(p);





p

:=q;

q

:=nil;

Таким образом, стандартные процедуры new и dispose позволяют динамически порождать объекты и уничтожать их, что дает возможность использовать память более эффективно.

Процедурой despose(p)надо пользоваться аккуратно. Использование вызова despose(p) может приводить к весьма неприятной ситуации, связанной с появлением так называемых “висячих” указателей: если два указателями адресовали одну и ту же область памяти (а это встречается очень часто), то вызов despose(p) с одной из них оставляет в другой переменной адрес уже освобожденной области памяти и повторное использование этой переменной приведет либо к неверному результату, либо к аварийному завершению программы.

Н

апример:

Var p,q:^integer;

……

new(p); new (q);

p^:=3;

q:=p;

despose(p);
Использование  Dispose для освобождения выделенной динамической памяти не является обязательным, после выхода из программы  динамическая  память освобождается автоматически, но частое использование процедуры выделения памяти без ее освобождения может привести к состоянию невозможности дальнейшего выделения памяти и к остановке  программы.

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

Program DemoPointer;

var p1,p2,p3:^Integer;

begin

p1:=NIL; p2:=NIL; p3:=NIL;

New(p1); New(p2); New(p3);

p1^:=2; p2^:=4;

p3^:=p1^+Sqr(p2^);

writeln('p1^=',p1^:3,' p2^=',p2^:3,' p3^=',p3^:3);

p1:=p2;

writeln('p1^=',p1^:3,' p2^=',p2^:3)

end.

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

p1^= 2 p2^= 4 p3^= 18

p1^= 4 p2^= 4
Пример 2. В динамическом массиве найти максимальный элемент.

type tm=array[1..10000] of integer;

var a:^tm;

n,i,max:integer;

begin writeln('input n');

readln(n);

randomize;

new(a);

for i:=1 to n do a^[i]:=random(100);

max:=a^[i];

for i:=2 to n do

if a^[i]>max then max:=a^[i];

writeln('max=',max);

dispose(a);

end.
Пример 3. Создать массив указателей и найти в нем минимальное значение.

var a:array[1..100] of ^real;

i,n:integer;

min:real;

begin writeln('input n');

readln(n);

randomize;

for i:=1 to n do

begin new(a[i]);

a[i]^:=random(10)-random;

writeln(a[i]^:6:2)

end;

min:=a[i]^;

for i:=2 to n do

if a[i]^
writeln('min=',min:6:2);

for i:=1 to n do dispose(a[i]);

end.

Пример 4. Дан текстовый файл размером не более 64 Кб, содержащий действительные числа, по одному в каждой строке. Переписать содержимое файла в массив, разместив его в динамически распределяемой памяти. Вычислить среднее значение элементов массива. Очистить динамическую память. Создать целый массив размером 10000, заполнить его случайными целыми числами в диапазоне от –100 до 100 и вычислить его среднее значение.

Program Srednee;

Const NMax = 10000;

Type Diapazon = 1..NMax;

MasInt = Array[Diapazon] Of Integer;

MasReal = Array[Diapazon] Of Real;

Var PInt : ^MasInt; PReal : ^MasReal;

I, Midint, N : longInt;

MidReal : Real;

T : Text;

S : string;

Begin

Write('Введите имя файла: ');

ReadLn(S);

Assign(T, S);

Reset(T);

MidReal := 0; MidInt := 0;

Randomize;

NEW(PReal); {Выделение памяти под вещественный массив}

{Ввод и суммирование вещественного массива}

I:=1;

While Not Eof (T) Do

Begin ReadLn(T, PReal^[I]);

MidReal := MidReal + PReal^[I];

I:=I+1;

End;

DISPOSE(PReal); {Удаление вещественного массива}

N:=I;

Close(T);

NEW(PInt); {Выделение памяти под целый массив}

{Вычисление и суммирование целого массива}

For I := 1 To N Do

Begin PInt^[I] := -100 + Random(201);

MidInt := MidInt + PInt^[I]

End;

{Вывод средних значений}

WriteLn('среднее целое равно: ', MidInt Div N);

WriteLn('среднее вещественное равно: ', (MidReal / N) : 10 : 6)

End.
Заключение

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

  2. Во время компиляции память выделяется только под статические величины. Указатели — это статические величины, поэтому они требуют описания.

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

  4. До присваивания значения ссылочной переменной (с помощью оператора присваивания или процедуры NEW) она является неопределенной.

  5. Ввод и вывод указателей не допускается.

  6. Работа с динамическими переменными происходит точно так же, как и со статическими переменными соответствующих типов.

  7. Подключение динамической памяти позволяет увеличить объем обрабатываемых данных. В версиях Турбо-Паскаля, работающих под операционной системой MS DOS, под данные одной программы выделяется 64 килобайта памяти (или, если быть точнее, 65520 байт). Это и есть статическая область памяти. При необходимости работать с большими массивами информации этого может оказаться мало. Размер динамической памяти — много больше (сотни килобайт).

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

  9. Использование динамической памяти позволяет создавать структуры данных переменного размера (списки, очереди, стеки, деревья).

  10. Работа с динамическими данными замедляет выполнение программы, т.к. доступ к величине происходит в два этапа: сначала ищется указатель, затем по нему – величина. Выигрыш в памяти компенсируется проигрышем во времени.

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

Здесь вы можете проверить себя по материалу этой темы.

Контрольные вопросы

  1. Чем отличаются статические и динамические величины?

  2. Какая память называется динамически распределяемой?

  3. Что такое указатель?

  4. Какие виды указателей вам известны?

  5. Как определяется адрес переменной?

  6. Приведите примеры объявления указателей.

  7. Как выделить память под динамическую переменную? Как освободить память от динамической переменной?

  8. Что такое "разыменование"?

  9. Что в языке Pascal обозначает константа Nil?

  10. В каком случае возможно присваивание указателей?

  11. Какие ситуации приводят к возникновению в динамически распределяемой памяти "мусора"?

Задание на дом:

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

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






Добавить документ в свой блог или на сайт

Похожие:

Программа по формированию навыков безопасного поведения на дорогах и улицах «Добрая дорога детства» 2 iconПрограмма по формированию навыков безопасного поведения на дорогах...
Проектно-образовательная деятельность по формированию у детей навыков безопасного поведения на улицах и дорогах города
Программа по формированию навыков безопасного поведения на дорогах и улицах «Добрая дорога детства» 2 iconПрограмма по формированию навыков безопасного поведения на дорогах...
Цель: Создание условий для формирования у школьников устойчивых навыков безопасного поведения на улицах и дорогах
Программа по формированию навыков безопасного поведения на дорогах и улицах «Добрая дорога детства» 2 iconПрограмма по формированию навыков безопасного поведения на дорогах...
«Организация воспитательно- образовательного процесса по формированию и развитию у дошкольников умений и навыков безопасного поведения...
Программа по формированию навыков безопасного поведения на дорогах и улицах «Добрая дорога детства» 2 iconПрограмма по формированию навыков безопасного поведения на дорогах...
Цель: формировать у учащихся устойчивые навыки безопасного поведения на улицах и дорогах, способствующие сокращению количества дорожно-...
Программа по формированию навыков безопасного поведения на дорогах и улицах «Добрая дорога детства» 2 iconПрограмма по формированию навыков безопасного поведения на дорогах...
Конечно, главная роль в привитии навыков безопасного поведения на проезжей части отводится родителям. Но я считаю, что процесс воспитания...
Программа по формированию навыков безопасного поведения на дорогах и улицах «Добрая дорога детства» 2 iconПрограмма по формированию навыков безопасного поведения на дорогах...
Поэтому очень важно воспитывать у детей чувство дисциплинированности и организованности, чтобы соблюдение правил безопасного поведения...
Программа по формированию навыков безопасного поведения на дорогах и улицах «Добрая дорога детства» 2 iconПрограмма по формированию навыков безопасного поведения на дорогах...
Всероссийский конкур сочинений «Пусть помнит мир спасённый» (проводит газета «Добрая дорога детства»)
Программа по формированию навыков безопасного поведения на дорогах и улицах «Добрая дорога детства» 2 iconПрограмма по формированию навыков безопасного поведения на дорогах...
Поэтому очень важно воспиты­вать у детей чувство дисциплинированности, добиваться, чтобы соблюдение правил безопасного поведения...
Программа по формированию навыков безопасного поведения на дорогах и улицах «Добрая дорога детства» 2 iconПрограмма по формированию навыков безопасного поведения на дорогах...

Программа по формированию навыков безопасного поведения на дорогах и улицах «Добрая дорога детства» 2 iconПрограмма по формированию навыков безопасного поведения на дорогах...

Программа по формированию навыков безопасного поведения на дорогах и улицах «Добрая дорога детства» 2 iconПрограмма по формированию навыков безопасного поведения на дорогах...

Программа по формированию навыков безопасного поведения на дорогах и улицах «Добрая дорога детства» 2 iconПрограмма по формированию навыков безопасного поведения на дорогах...

Программа по формированию навыков безопасного поведения на дорогах и улицах «Добрая дорога детства» 2 iconПрограмма по формированию навыков безопасного поведения на дорогах...

Программа по формированию навыков безопасного поведения на дорогах и улицах «Добрая дорога детства» 2 iconПрограмма по формированию навыков безопасного поведения на дорогах...

Программа по формированию навыков безопасного поведения на дорогах и улицах «Добрая дорога детства» 2 iconПрограмма по формированию навыков безопасного поведения на дорогах...

Программа по формированию навыков безопасного поведения на дорогах и улицах «Добрая дорога детства» 2 iconПрограмма по формированию навыков безопасного поведения на дорогах...



Школьные материалы


При копировании материала укажите ссылку © 2013
контакты
100-bal.ru
Поиск