Консультация № 197979
15.03.2020, 19:45
0.00 руб.
0 3 1
Уважаемые эксперты! Пожалуйста, ответьте на вопрос:
Добрый день подскажите пожалуйста по работе есть задание и есть версия, у вас на сайте уже есть такая но раскрыто не в полной мере.


Приложение:
ЗАДАНИЕ 1

1). Описать переменные-указатели R1,R2, связанные с вещественным типом; I1,I2 – связанные с типом Integer; St - со строкой, не превышающей по длине 15 символов; RRec - с записью с двумя полями:Str типа String[l2] и I типа lnteger. При этом R1 и I1, St и RRec описать с предварительным определением типа, a R2 и I2 -без предварительного опре-деления типа.

2). Можно ли переменные St и RRec описать без предварительного определения типа?

3). Описать нетипизированные указатели РР, РР1, РР2.

1.2. Операции с указателями:

Для указателей в Турбо Паскале допустимы только операции присваивания и сравнения. Указателю можно присваи-вать содержимое другого указателя того же типа или стандартную константу NIL (пустой указатель), совместимую по присваиванию с указателями любых типов.

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

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

PINT^ :=4;

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

ЗАДАНИЕ 2

1) Проверить, совпадает ли начальное значение текущего указателя кучи с указателем HeapOrg.

2) Дать значение переменным R1 и I1 с помощью процедуры New. Проследить за перемещением указателя HeapPtr с помощью печати результатов операций сравнения для указателей. Для запоминания текущего значения использо-вать указатель PP.

3) Дать значения указателей R2 и I2, присвоив им значения указателей R1 и I1. Что при этом произойдет с указателем HeapPtr?

4) Дать произвольные допустимые значения динамическим переменным, на которые указывают переменные R1 и I1. При этом первую из этих динамических переменных ввести с клавиатуры, а второй присвоить целую часть первой. Вывести значения ссылочных (динамических) переменных, записанных в динамической области памяти во фрагмен-тах, связанных с указателями R1,R2,I1,I2. Результат пояснить.

5) Запомнить текущее значение HeapPtr в РР1. С помощью процедуры New задать значение переменной St, запом-нить значение HeapPtr в РР2 и с помощью процедуры New задать значение указателя RRec, затем ввести значения соответствующих динамических переменных с клавиатуры.

Вывести размер занимаемой памяти для St, RRec и соответствующих динамических переменных (использовать функ-цию SizeOf). Результат пояснить. Вывести значения строки и записи, на которые указывают St и RRec.

Можно ли в программе записать:

a) St:= RRec; b) Writeln(St); c) Write(Rrec.Str); Какова реакция системы? Ответ пояснить.

6) Что произойдет с указателем HeapPtr при освобождении указателя St с помощью процедуры Dispose?

Что произойдет с HeapPtr при освобождении указателя RRec с помощью процедуры Dispose?

Указание. При решении можно использовать для соответствующих операций сравнения значения указателей РР1 и РР2.

Работа-----------------------------
program heap;
type
MRecord = record
Str: string[12];
I: integer;
end;

MString = string[15];
MReal = real;
MInteger = integer;
{pRec = ^mRecord;}

var
R2, R1: ^real;

I2, I1: ^integer;
{ I2: ^MInteger; }
St: ^MString;
Rrec: ^mRecord;
{RRec:pRec;}
pp, pp1, pp2: pointer;
HeapOrg: pointer;
HEAPPTR: pointer;

begin
write('HeapOrg = HeapPrt? ');
writeln(HEAPORG = HEAPPTR);
pp:=heapptr;
New(R1);
New(I1);
writeln('HeapPtr = pp? ',HeapPtr=pp);
R2:=R1;
I2:=I1;

write('Enter R2: ');
readln(r2^);
i2^:=trunc(r2^);
writeln('I2 = ',i2^);
writeln('r1= ',r1^, ' r2= ',r2^, ' i1= ',i1^, ' i2= ',i2^);
pp1:=HeapPtr;
New(St);
Write('Read String: ');
readln(St^);
writeln('pp1 = HP? ', pp=HeapPtr,' ', HeapPtr=pp1);
New(RRec);
pp2:=HeapPtr;
writeln('Enter RRec.Int & Rrec.Str: ');
readln(RRec^.I, RRec^.Str);
writeln('pp1 = HP? ', pp1=heapptr,' ',pp2=heapptr);
writeln('Size of Rrec: ',sizeof(RRec^.I));
writeln('Size of Str: ', sizeof(St^.Length));
dispose(st);
writeln('pp2= HP? ', pp2=heapptr);
writeln('pp1= HP? ', pp1=heapptr);
dispose(rrec);
writeln('pp2= HP? ', pp2=heapptr);
writeln('pp1=HP? ', pp1=heapptr);

end.

Обсуждение

давно
Старший Модератор
31795
6196
16.03.2020, 15:16
общий
Адресаты:
Цитата: Voran4ik
Для указателей в Турбо Паскале допустимы только операции присваивания и сравнения.

Утверждать, что к указателям можно применить только сравнение или присваивание - не корректно.
Типизированные указатели, такие-же переменные, того или иного типа, как и обычные. Разница в том, что под первые нужно выделять память в ходе выполнения программы, под вторые память выделяется во время компиляции программы, т.е. где они размещены - в динамической памяти(первые), в сегменте данных(вторые), В любом случае: переменная или указатель(любого типа) - это адрес, который указывает на некоторый блок памяти(в том числе и нулевой длины - для разменованных, или не типизированных указателей).

К примеру NEW и GETMEM:
New (процедура)
Создает новую динамическую переменную и устанавливает на нее указатель.
Объявление: Procedure New(Var P : Pointer [, Init : Constructor ])

GetMem (процедура)
Создает динамическую переменную определенного размера и записывает ее адрес в памяти в указательную переменную.
Объявление: Procedure GetMem(Var P : Pointer; Size : Word);

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

Цитата: Voran4ik
Указателю можно присваивать содержимое другого указателя того же типа или стандартную константу NIL (пустой указатель), совместимую по присваиванию с указателями любых типов

NIL - константа равная 0х0000, т.е. это адрес равный нулю, но в куче не может быть нулевого адреса, по этому и выбрали такое значение.

Цитата: Voran4ik
Работа

Программа работает так:

Одна ошибка:sizeof(St^.Length): в ТР нет такого свойства строки..

ps: Советую найти книгу: Пильщиков В. Программирование на языке ассемблер IBM PC.
В главе 10.3.3 Организация кучи. Есть много теоритической информации по организации кучи, для того, чтобы на ассемблере создать аналог кучи своими руками. Если не обращать внимание на код, то остальная информации будет полезна.

Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Старший Модератор
31795
6196
22.03.2020, 22:08
общий
Адресаты:
тема указателей обширна, что именно Вам не понятно.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Старший Модератор
31795
6196
25.03.2020, 11:04
общий
это ответ
Здравствуйте, Voran4ik!

Ткма Указателей обширна, с одной стороны там все просто, но с другой не все так отнозначно.
Цитата: Voran4ik
Для указателей в Турбо Паскале допустимы только операции присваивания и сравнения.

Ну с присваиванием все ясно, указатель должен как-то получать некоторое значение, а вот со сравнением - сложнее.
Цитата: Помощь
Операторы сравнение: =, < , > и их комбинации

К указателям можно применить только =, но не которые диалоги PASCAL допускают ещё и <>, и больше ничего.

Типизированные указатели, такие-же переменные, того или иного типа, как и обычные. Разница в том, что под первые нужно выделять память в ходе выполнения программы, под вторые память выделяется во время компиляции программы. Любая переменная, представляет собой адрес и длину конкретного типа. Компилятор при создании программы, применяет к этим переменным методы характерные для данного типа.

Цитата: Voran4ik
Можно ли переменные St и RRec описать без предварительного определения типа?

Паскаль разрешает создавать указатели, только зарегистрированных типов.


Цитата: Voran4ik
Что при этом произойдет с указателем HeapPtr?


Подробности можно узнать тут.

Удачи!
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Форма ответа