Примеры использования указателей

Пример: создать в динамической памяти массив из переменных вещественного типа размерностью 100 * 200.

Для решения данной задачи воспользуемся следующими функциями:

Seg(x) – возвращает сегментную часть адреса;

Ofs(x) – возвращает смещение.

(Тип обоих функций – word).

Аргументом xпри обращении к этим функциям может служить любая переменная, в том числе и та, на которую указывает указатель.

С помощью встроенной функции

 

Ptr (seg, ofs: word): pointer

 

можно создать значение указателя совместимое с указателями любого типа.

Для рассматриваемого примера удобно резервировать фрагменты такой длины, чтобы в них могли, например, разместиться строки прямоугольной матрицы, т.е. 200 * 6 = 1200 байт. Начало каждого фрагмента, т.е. фактически начало размещения в памяти каждой строки, запоминается в массиве PtrStr, состоящем из 100 указателей. Теперь для доступа к любому элементу строки нужно вычислить смещение этого элемента от начала строки и сформировать соответствующий указатель:

 

 

Var

i, j: integer;

PtrStr : array [1..100] of pointer;

pr : ^real;

Const

SizeOfReal = 6;

 

Begin

for i := 1 to 100 do

GetMem (PtrStr[i], SizeOfReal * 200);

{Обращение к элементу матрицы [i,j]}

pr := Ptr(Seg (PtrStr[i]^), Ofs (PtrStr[i]^) + (j – 1) * SizeOfReal);

End.

 

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

 

const

SizeOfReal = 6; {Длина переменной типа REAL}

N = 100; {Количество столбцов}

М = 200; {Количество строк}

 

var

i, j: integer;

PtrStr: array [1..N] of pointer;

s : real;

 

type

RealPoint = ^real;

 

 

function AddrR (i, j : word): RealPoint;

{Функция по сегменту i и смещению j выдает адрес вещественной переменной}

begin

AddrR := Ptr (Seg (PtrStr[i]^), Ofs (PtrStr[i]^)+(j –1)* SizeOfReal);

End;

 

function GetR (i, j: integer): real;

{Функция выдает значение вещественной переменной по сегменту i смещению j ее адреса}

begin

GetR := AddrR (i, j)^;

End;

 

procedure PutR (i, j : integer; x: real);

{Процедура помещает в переменную, адрес которой имеет сегмент i смещение j, вещественное значение х}

begin

AddrR (i, j)^ := x;

end;

 

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

begin

for i :=1 to N do

begin

GetMem (PtrStr[i], M * SizeOfReal);

for j := 1 to M do

PutR (i, j, Random)

end;

s := 0;

for i := 1 to N do

for j := 1 to M do

s := s + GetR(i,j);

WriteLn (s / (N * M) : 12:10)

end.

Динамические списковые структуры

 

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

 

Type

link = ^zap;

dan =…;

zap = record;

pole1: link;

pole2: dan;

end;

 

Var

p: link;

 

link – это указатель на область памяти для записи переменных типа zap.

Тип zap оказывается записью, где имеются поля, содержащие информацию (типа dan) и одно поле pole1 типа link, т.е. указатель. Указатель указывает на следующую запись того же самого типа.

Переменная p есть указатель на область памяти, где можно хранить запись. С помощью оператора New(pul) резервируется область памяти для хранения записи и одно из полей этой записи может содержать указатель, который в свою очередь мог указывать на другую запись.

Образуется последовательность следующего вида (рис. 5):

 

 


Рис. 5. Последовательность записей в динамическом списке

 

Для заполнения полей можно использовать операторы присваивания:

 

pul^.имя поля := значение;

 

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

Type

link = ^zap;

zap = record;

pole1: link;

pole2:integer;

end;

 

Var

z, p: link;

Begin

{Запись чисел}

z:=nil;

for k:=1 to 5 do

Begin

new(p);

p^.pole2:=k;

p^.pole1:=z;

z:=p;

end;

{Считывание в обратном порядке}

for k:=1 to 5 do

Begin

WriteLn(p^.pole2);

p:=p^.pole1;

end;

End.

 

Считывание чисел также можно осуществить следующим образом:

 

while p<>nil do

Begin

WriteLn(p^.pole2);

p:=p^.pole1;

end;

 

Пример. Построить список, элементы которого содержат квадраты чисел 1,2, …, n.

 

Type

cc=^zap;

zap = record;

pl1: integer;

pl2: cc;

end;

 

Var

p,q: cc;

i,n: integer;

 

Begin

WriteLn(‘введите n’);

ReadLn(n);

p:=nil;

for i:=n downto 1 do

Begin

New(q);

q^.pl1:=sqr(i);

q^.pl2:=p;

p:=q;

End;

q:=p;

while q<>nil do

Begin

Write(q^.pl1);

q:=q^.pl2;

End;

Dispose(p);

Dispose(q); }

End.

 

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

Type

ck=^tip;

tip=record

inf: integer;

cled: ck;

end;

 

Var

p,q: ck;

i,j: integer;

 

Begin

p:=nil;

WriteLn(‘Введите нечетное количество целых чисел’, j);

for i:=1 to j do

Begin

New(q);

Read(q^.inf);

q^.cled:=p;

p=q;

end;

for i:=1 to j div 2 do

q:=q^.cled;

WriteLn(q^.inf);

End.

Пример. Построить список, состоящий из записей, содержащих сведения о студенте: ФИО, экзаменационные оценки по физике, математике и программированию.

Вывести список на экран в виде таблицы и подсчитать средний балл.

 

uses Crt;

Type

pst=^st;

 

st=record

fio: string[20];

math: integer;

phys: integer;

prog: integer;

pt: pst;

end;

 

Var

q, p: pst;

i, j, n: integer;

d: real;

 

Begin

ClrScr;

Write(‘Введите число записей’);

ReadLn(n);

p:=nil;

for i:=1 to n do

Begin

New(q);

WriteLn(‘Введите ФИО’);

ReadLn(q^.fio);

WriteLn(‘Введите оценку по математике’);

ReadLn(q^.math);

WriteLn(‘Введите оценку по физике’);

ReadLn(q^.phys);

WriteLn(‘Введите оценку по программированию’);

ReadLn(q^.prog);

q^.pt:=p;

p:=q;

end;

q:=p;

WriteLn;

for j:=1 to 56 do

Write(‘-‘);

WriteLn;

WriteLn(‘| fio stud | math | phys | prog | sr. ball |’);

for j:=1 to 56 do

Write('-');

WriteLn;

for i:=1 to n do

Begin

d:=(q^.math + q^.phys + q^.prog)/3;

WriteLn(‘| ‘, q^.fio:20, ‘ | ‘, q^.math:4, ‘ | ‘,q^.phys:4, ‘ |

‘,q^.prog:4, ‘ | ‘, d:8:2,’ |’);

q:=q^.pt;

end;

for j:=1 to 56 do

Write(‘-‘);

WriteLn;

Dispose(p);

Dispose(q);

ReadLn;

End.

Альтернативный вариант предыдущей программы, но список выводится в правильном порядке.

uses Crt;

Type

pst=^st;

st=record

fio: string[20];

math: integer;

phys: integer;

prog: integer;

pt: pst;

End;

 

Var

nach, q, p : pst;

i ,j ,n : integer;

d : real;

 

Begin

ClrScr;

Write(‘Введите число записей’);

ReadLn(n);

New(q);

for i:=1 to n do

Begin

q^.pt:=nil;

if i = 1 then nach:=q;

WriteLn(‘Введите ФИО’);

ReadLn(q^.fio);

WriteLn(‘Введите оценку по математике’);

ReadLn(q^.math);

WriteLn(‘Введите оценку по физике’);

ReadLn(q^.phys);

WriteLn(‘Введите оценку по программированию’);

ReadLn(q^.prog);

p:=q;

New(q);

if i<>n then p^.pt:=q

Else

Dispose(q);

end;

WriteLn;

for j:=1 to 56 do

Write(‘-‘);

WriteLn;

WriteLn(‘| fio stud | math | phys | prog | sr. ball |’);

for j:=1 to 56 do

Write(‘-‘);

WriteLn;

q:=nach;

while q<>nil do

Begin

d := (q^.math + q^.phys + q^.prog)/3;

WriteLn(‘| ‘, q^.fio:20, ‘ | ‘, q^.math:4, ‘ | ‘,q^.phys:4,

‘ | ‘,q^.prog:4, ‘ | ‘, d:8:2,’ |’);

q:=q^.pt;

end;

for j:=1 to 56 do

Write(‘-‘);

WriteLn;

Dispose(p);

Dispose(q);

ReadLn;

end.

 








Дата добавления: 2017-01-29; просмотров: 671;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.057 сек.