Понятие указателя. Статические и динамические переменные.
Указатель - это ссылка на данные или код вашей программы. Он представляет адрес в памяти элемента, на который указывает. Использование указателей позволяет писать большие и более гибкие программы и особенно полезно, когда вы начинаете писать объектно-ориентированные программы.
Указатель - это какой-либо адрес в памяти вашего компьютера. Это может быть адрес переменной, записи данных, либо процедуры или функции. Обычно вам не важно, где расположен элемент в памяти. Вы можете просто ссылаться на него по имени, и Borland Pascal знает, где его нужно искать.
Именно это происходит, когда вы описываете переменную. Например, если программа включает в себя следующий код, то вы указываете компилятору на необходимость зарезервировать область в памяти, на которую будете ссылаться по имени SomeNumber.
var SomeNumber: Integer;
Карта памяти. Динамическое распределение памяти. Создание и уничтожение динамических переменных.
Динамически распределяемая область памяти - это вся память, которую ваша операционная система делает доступной для программы и которая не используется ее кодом, сегментом данных и стеком. Объемом распределяемой динамической памяти вы можете управлять с помощью директивы компилятора $M. Обычно в Borland Pascal вы можете зарезервировать память в динамически распределяемой области, получить к ней доступ через указатель, а затем снова освободить память. Подробности о распределении памяти в динамически распределяемой области вы можете найти ниже в разделе "Как использовать указатели?" Одним из наиболее важных моментов использования указателей является распределение динамических переменных в динамически распределяемой области памяти. Borland Pascal предусматривает два способа выделения для указателя памяти: процедура New и процедура GetMem.
Пример 4: Динамическое распределение памяти для строки.
type PString=^String;
var
ReadBuffer: String;
LinewRead: array[1..1000] of PString;
TheFile: Text;
LineNumber: Integer;
begin
Assign(TheFile, 'FOO.TXT');
Reset(TheFile);
for LineNumber := 1 to 1000 do
begin
Readln(ReadBuffer);
GetMem(LinesRead[LineNumber], Length(ReadBuffer)+1);
LinesRead[LineNumber]^:=ReadBuffer;
end;end.
Фрагментация динамической памяти. Освобождение динамической памяти.
Память, распределенная для переменных с помощью New (выделение в динамически распределяемой облатсти), после завершения работы с ними должна освобождаться. Это позволит использовать динамически распределяемую память для других переменных. Нужно помнить, что если вы распределяете динамические переменные с помощью New, то освобождать выделенную для них память после завершения работы с этими переменными нужно с помощью Dispose (освобождение выделенной записи).
12-Однонаправленный список:
Unit Spisok;
Interface
Type BT = LongInt;
U = ^Zveno;
Zveno=Record Inf:BT;Next:U End;
Procedure_V_Nachalo(Var First : U; X : BT);
Procedure_Iz_Nachala(Var First:U;Var X:BT);
Procedure V_Spisok(Pred : U; X : BT);
Procedure Iz_Spiska(Pred : U; Var X : BT);
Procedure Ochistka(Var First: U);
Function Pust(First : U) : Boolean;
Procedure Print(First : U);
procedure zapol(var First:U);
Implementation
Procedure V_Nachalo;
Var Vsp : U;
Begin New(Vsp);
Vsp^.Inf := X;
Vsp^.Next := First;
First := Vsp; End;
Procedure Iz_Nachala;
Var Vsp : U;
Begin Vsp := First;
First := First^.Next;
X := Vsp^.Inf;
Dispose(Vsp); End;
Procedure V_Spisok;
Var Vsp : U;
Begin New(Vsp);
Vsp^.Inf := X;
Vsp^.Next := Pred^.Next;
Pred^.Next := Vsp; End;
Procedure Iz_Spiska;
Var Vsp : U;
Begin Vsp := Pred^.Next;
Pred^.Next := Pred^.Next^.Next;
X := Vsp^.Inf;
Dispose(Vsp); End;
Procedure Ochistka;
Var Vsp : BT;
Begin While Not Pust(First) Do Iz_Nachala(First, Vsp) End;
Function Pust;
Begin Pust := First = Nil End;
Procedure Print;
Var Vsp : U;
Begin Vsp := First;
While Vsp <> Nil Do
Begin
Write(Vsp^.inf: 6);
Vsp := Vsp^.Next;
End; WriteLn End;
procedure zapol;
var v:U;i,n:integer;a:Bt;
begin
write('vvedite kol-vo el-ov v spiske:');
readln(n);
a:=-10+random(21);
V_Nachalo(First,a);
v:=First;
for i:=2 to n do
begin a:=-10+random(21);
V_Spisok(v,a);
v:=v^.next; end;end;
Begin
End.
14-Кольцевой список:
Unit Spis;
Interface
type BT=longint;
U=^zveno;
zveno=record
inf:BT;
P,N:U;
end;
procedure V_Nachalo(var first:U;x:BT);
procedure V_Spisok(pred:U;x:BT);
procedure Print(first:U);
function vvod:U;
Implementation
procedure V_Nachalo;
var vsp:U;
begin
new(vsp);
vsp^.inf:=x;
vsp^.P:=first^.P;
vsp^.N:=first;
first^.P^.N:=vsp;
first^.P:=vsp;
first:=vsp;
end;
function vvod;
var v,S:U;x:BT;k,i:integer;
begin
write('vvedite kol-vo elem-ov');
readln(k);
x:=-100+random(201);
new(s);
s^.inf:=x;
s^.P:=s;
s^.N:=s;
v:=S;
for i:=2 to k do
begin
x:=-100+random(201);
V_Spisok(v,x);
v:=v^.N;
end;
vvod:=S;
end;
procedure V_Spisok;
var vsp:U;
begin
new(vsp);
vsp^.inf:=x;
vsp^.P:=pred;
pred^.N^.P:=vsp;
vsp^.N:=pred^.N;
pred^.N:=vsp;
end;
procedure Print;
var vsp:U;i:boolean;
begin
i:=true;
vsp:=first;
while (vsp<>first)or(i) do
begin
i:=false;
write(vsp^.inf:5);
vsp:=vsp^.N;
end;
writeln;
end;
Begin
end.
19-Модуль. Общая структура модуля. Компиляция и подключение модуля:
Модуль (UNIT) в TURBO PASCAL - это особым образом оформленная библиотека подпрограмм. Модуль в отличие от программы не может быть запущен на выполнение самостоятельно, он может только участвовать в построении программ и других модулей. Модули позволяют создавать личные библиотеки процедур и функций и строить программы практически любого размера. Модуль в TURBO PASCAL представляет собой отдельно хранимую и независимо компилируемую программную единицу. В общем случае модуль - это совокупность программных ресурсов, предназначенных для использования другими программами. Под программными ресурсами понимаются любые элементы языка TURBO PASCAL: константы, типы, переменные, подпрограммы. Модуль сам по себе не является выполняемой программой, его элементы используются другими программными единицами. Все программные элементы модуля можно разбить на две части: - программные элементы, предназначенные для использования другими программами или модулями, такие элементы называют видимыми вне модуля; - программные элементы, необходимые только для работы самого модуля, их называют невидимыми или скрытыми. В соответствии с этим модуль, кроме заголовка, содержит две основные части, называемые интерфейсом и реализацией. В общем случае модуль имеет следующую структуру:
unit <имя модуля>; {заголовок модуля}
interface
{описание видимых программных элементов модуля}
{описание скрытых программных элементов модуля}
begin
{операторы инициализации элементов модуля}
end.
В частном случае модуль может не содержать части реализации и части инициализации, тогда структура модуля будет такой:
unit <имя модуля>; {заголовок модуля}
interface
{описание видимых программных элементов модуля}
implementation
end.
Использование в модулях процедур и функций имеет свои особенности. Заголовок подпрограммы содержит все сведения, необходимые для ее вызова: имя, перечень и тип параметров, тип результата для функций, эта информация должна быть доступна для других программ и модулей. С другой стороны, текст подпрограммы, реализующий ее алгоритм, другими программами и модулями не может быть использован. Поэтому заголовок процедур и функций помещают в интерфейсную часть модуля, а текст - в часть реализации. Интерфейсная часть модуля содержит только видимые (доступные для других программ и модулей) заголовки процедур и функций (без служебного слова forward). Полный текст процедуры или функции помещают в часть реализации, причем заголовок может не содержать список формальных параметров. Исходный текст модуля должен быть откомпилирован с помощью директивы Make подменю Compile и записан на диск. Результатом компиляции модуля является файл с расширением .TPU (Turbo Pascal Unit). Основное имя модуля берется из заголовка модуля. Для подключения модуля к программе необходимо указать его имя в разделе описания модулей, например:
uses CRT,Graph;
В том случае, если имена переменных в интерфейсной части модуля и в программе, использующей этот модуль, совпадают, обращение будет происходить к переменной, описанной в программе. Для обращения к переменной, описанной в модуле, необходимо применить составное имя, состоящее из имени модуля и имени переменной, разделенных точкой. Например, пусть имеется модуль, в котором описана переменная К:
unit M;
interface
var K: Integer;
implementation
.................
end.
Пусть программа, использующая этот модуль, также содержит переменную К:
Program P;
uses M;
var K: Char;
begin
.............
end.
Для того, чтобы в программе P иметь доступ к переменной K из модуля M, необходимо задать составное имя M.K. Использование составных имен применяется не только к именам переменных, а ко всем именам, описанным в интерфейсной части модуля. Рекурсивное использование модулей запрещено. Если в модуле имеется раздел инициализации, то операторы из этого раздела будут выполнены перед началом выполнения программы, в которой используется этот модуль.
22-Построение диаграмм.Пос-ие гр-ов ф-ий.Анимация:
1)Круговые диаграммы
В круговой диаграмме каждому элементу последовательности соответствует сектор, градусная мера которого пропорциональна величине элемента. Для построения круговой диаграммы необходимо просуммировать все элементы последовательности, после чего найти отношения каждого из элементов к полученной сумме (так будет вычислено, какую часть круга нужно поставить в соответствие данной величине,—т.е. рассчитываются доли круга, приходящиеся на данную величину, если весь круг принять равным
1) Все эти расчеты можно представить формулами ; . Затем эти относительные величины переводятся в градусы:
Алгоритм в этом случае будет следующим: 1)вычислить сумму элементов последовательности; 2)найти величину сектора, соответствующего каждой величине; 3)построить все секторы в графическом режиме (в результате должен получиться полный круг). Желательно каждый сектор строить своим цветом, или использовать разную штриховку, если секторы одноцветные.
Program Kr_D;
Uses Graph;
Var a,S:Real;I:Byte;G,M:Integer;
Xc,Yc,R:Integer; {координаты центра круга и его радиус}
F:Text; {файл содержит данные для построения диаграммы}
Alpha : Integer; {угол, соответствующий очередной величине}
SAngle : Integer; Stroka : String;
Begin
Assign(F, '1.dat'); Reset(F);
S:=0; {сумма элементов последовательности}
While Not Eof(F) Do
begin Readln(F, a); S := S + a end;
reset(f); G := detect; M := 0;
initgraph(G, M, '');
Xc := GetMaxX Div 2; Yc := GetMaxY Div 2;
R := 100; SAngle := 0; i := 1;
While Not Eof(f) Do begin
Readln(F, a);
Alpha := round(A / S * 360); {вычисление угла}
setcolor(i mod 16+1); setfillstyle(1,i mod 16+1);
{построение сектора, соответствующего величине}
sector(Xc, Yc, SAngle, SAngle+Alpha,R, R);
SAngle := SAngle + Alpha; i:= i + 1;
{укажем, какому цвету какая величина соответствует}
bar(Xc+200,Yc-250+(i-1)*20,Xc+220,Yc-250+(i-1)*20+15);
str(a:8:2, stroka);
outtextxy(Xc+230,Yc-250+5+(i-1)*20,stroka)
end;
readln; close(F); closegraph End.
2)Столбчатые диаграммы
Для построения диаграммы выделим на экране прямоугольную область с координатами соответственно верхнего левого угла (Xlv, Ylv) и правого нижнего (Xpn, Ypn). Высота столбца диаграммы, соответствующего максимальному элементу последовательности, будет совпадать с высотой прямоугольника. Ширина столбца будет зависеть от количества элементов последовательности: чем больше компонент, тем меньшей будет ширина. Таким образом, для построения диаграммы нужно определить количество компонентов последовательности и максимальный элемент последовательности. Высота vi очередного столбца диаграммы на экране будет определяться формулой: , где xmax — максимальный элемент последовательности, xi — очередной элемент последовательности. Алгоритм построения диаграммы следующий: 1)определить количество элементов последовательности и её максимальный элемент; 2)согласно указанной формуле построить столбцы диаграммы. Их ширина на экране может быть рассчитана по формуле: , где n — количество элементов последовательности.
Program Stol_D;
Uses Graph;
Var a, xmax : Real; I, n : Byte; G, M : Integer;
F : Text; {файл содержит данные для построения диаграммы}
Stroka : String;
Xlv, Ylv, Xpn, Ypn : Integer; {координаты окна вывода диаграммы}
Begin
Assign(F, '1.dat'); Reset(F);
if not eof(f) then begin readln(f, xmax); n:=1 end
else n:=0;
While Not Eof(F) Do
begin Readln(F,a); if a>xmax then xmax:=a;
n:=n+1 end;
reset(f); G:=detect; M := 0;
initgraph(G,M,' '); Xlv:=50; Ylv:=50; Xpn:=GetMaxX-100; Ypn:=GetMaxY-50;
i:=0; {номер столбца}
While Not Eof(f) Do
begin
Readln(F, a);
setcolor(i mod 16+1); setfillstyle(1,i mod 16+1);
{очередной столбец}
bar(round(Xlv+i*(Xpn-Xlv)/n),Ypn,round(Xlv+(i+1)*(Xpn-Xlv)/n), round(Ypn-(Ypn-Ylv)/xmax*a));
i:=i+1;
{укажем, какому цвету какая величина соответствует}
bar(getMaxx-70,50+(i-1)*20,getMaxx-50,50+(i-1)*20+15);
str(a:8:2, stroka);
outtextxy(getMaxx-40, 50+(i-1)*20+8,stroka);
end;
readln; close(F); closegraph
End.
3)Линейные диаграммы
При построении линейных диаграмм каждой величине соответствует точка, расположенная на определённой высоте относительно начала отсчёта (высота рассчитывается так же, как и при построении столбчатых диаграмм), все точки соединяются линиями. В результате получается ломаная. Такого рода диаграммы чаще всего строя в тех случаях, когда необходимо визуализировать динамику изменения величин.
Программа аналогична программе построения столбчатых диаграмм и приведена ниже.
program Stol_D;
Uses Graph;
Var a, xmax : Real; I, n : Byte; G, M : Integer;
F : Text; {файл содержит данные для построения диаграммы}
Stroka : String; Yn, Yk : Integer;
Xlv, Ylv, Xpn, Ypn : Integer;
{координаты окна вывода диаграммы}
Begin
Assign(F, '1.dat'); Reset(F);
if not eof(f) then begin readln(f, xmax); n:=1
end else n := 0;
While Not Eof(F) Do
begin Readln(F, a); if a > xmax then xmax :=a;
n := n + 1 end;
reset(f); G := detect; M := 0;
initgraph(G, M, ''); Xlv := 50; Ylv := 50; Xpn:= GetMaxX-100; Ypn:= GetMaxY-50;
line(xlv, ylv, xlv, ypn); line(xlv, ypn, xpn, ypn);
i:= 0; {номер точки}
readln(f, a);
Yn := round(Ypn-(Ypn-Ylv)/xmax*a);
str(a:5:1, stroka);
outtextxy(round(Xlv+i*(Xpn-Xlv)/n)-20, Ypn+20, stroka);
While Not Eof(f) Do
begin
setcolor(i mod 16+1);setfillstyle(1, i mod 16+1);
{укажем, какому цвету какая величина соответствует}
Readln(F, a);
Yk := round(Ypn-(Ypn-Ylv)/xmax*a);
{очередная линия}
line(round(Xlv+i*(Xpn-Xlv)/n), Yn,
round(Xlv+(i+1)*(Xpn-Xlv)/n), Yk);
i:= i + 1;
str(a:5:1, stroka);
outtextxy(round(Xlv+i*(Xpn-Xlv)/n)-20,Ypn+20,stroka);
Yn := Yk;
{запоминаем положение очередной точки}
end;
readln; close(F); closegraph
End.