Все выпуски  

RFpro.ru: Программирование на Delphi и Lazarus


РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты по данной тематике

Евгений/Genia007/
Статус: Профессионал
Рейтинг: 172
∙ повысить рейтинг »
Асмик Гаряка
Статус: Советник
Рейтинг: 78
∙ повысить рейтинг »
Хватов Сергей
Статус: Академик
Рейтинг: 48
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И СОФТ / Программирование / Pascal / Delphi / Lazarus / Python

Номер выпуска:1678
Дата выхода:24.04.2016, 13:51
Администратор рассылки:Зенченко Константин Николаевич (Модератор)
Подписчиков / экспертов:20 / 18
Вопросов / ответов:1 / 1

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

Консультация # 189190:

Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос:

Вот задания:
1). Описать переменные-указатели R1,R2, связанные с веществен¬ным типом; I1,I2 – связанные с типом Integer; St - со строкой, не превышающей по длине 15 символов; RRec - с записью с двумя полями:Str типа String[l2] и I типа lnteger. При этом R1 и I1, St и RRec описать с предварительным определением типа, a R2 и I2 -без предварительного определения типа.
Проверить, совпадает ли начальное значение текущего указа¬теля кучи с указателем HeapOrg.
2). Дать значение переменным R1 и I1 с помощью процедуры New. Проследить за перемещением указателя HeapPtr с помощью печати результатов операций сравнения для указателей. Для запоминания текущего значения использовать указатель PP.
Дать значения указателей R2 и I2, присвоив им значения ука¬зателей R1 и I1. Что при этом произойдет с указателем HeapPtr?
3). Дать произвольные допустимые значения динамическим пе¬ременным, на кот орые указывают переменные R1 и I1. При этом первую из этих динамических переменных ввести с клавиатуры, а второй присвоить целую часть первой. Вывести значения ссылоч¬ных (динамических) переменных, записанных в динамической обла¬сти памяти во фрагментах, связанных с указателями R1,R2,I1,I2. Результат пояснить.
4). Запомнить текущее значение HeapPtr в РР1. С помощью про¬цедуры New задать значение переменной St, запомнить значение HeapPtr в РР2 и с помощью процедуры New задать значение указа¬теля RRec, затем ввести значения соответствующих динамических переменных с клавиатуры.
5). Вывести размер занимаемой памяти для St, RRec и соответству¬ющих динамических переменных (использовать функцию SizeOf). Результат пояснить. Вывести значения строки и записи, на кото¬рые указывают St и RRec.




А вот программа:

Код (Pascal) :: выделить код
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;

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^));
writeln('Size of Str: ', sizeof(st^));
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.


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

Дата отправки: 14.04.2016, 13:29
Вопрос задал: Посетитель - 399158 (Посетитель)
Всего ответов: 1
Страница онлайн-консультации »


Консультирует Зенченко Константин Николаевич (Модератор):

Здравствуйте, Посетитель - 399158!

Судя по вопросам, это лабораторная работа по изучению динамической памяти и её свойств. Под динамическукую память, при запуске программы отводится один сегмент размером 64кб, называемой кучей. При инициализации кучи, формируется список свободной памяти (ССП) и заполняются переменные HeapList, HeapLimit, HeapBlock, HeapAllocFlags, HeapError, HeapEnd, HeapOrg, HeapPtr.
При использовании функций New или GetMem, уменьшается ССП, соответсвенно изменяются переменные(см. раньше) и возвращают адрес выделенного участка памяти. При освобождении памяти функциями Dispose или FreeMem, увеличивается ССП, именяются переменные и освобождается память по переданному адресу.

Смысл указателя - адрес, который ссылается на некоторый участок памяти, длиной соответсвенно заданому типу. При использовании стандартных типов компилятор паскаля использует методы данного типа, если используется пользовательский тип, то программист должен инструмен тарий делать сам. Есть ещё нетипизированный указатель pointer. Указатели одно из самых мощных средств программирования. Приведу несколько примеров нестандартной работы с указателями.

1)Функции CHR и ORD, вернее без них:

Код (Pascal) :: выделить код
var
  lpChar:^char;{указатель на символ}
  lpByte:^byte;{указатель на байт}
  lpNull:pointer;{нетипизированный указатель}
begin
  write('enter:');{выводим сообщение}
  readln(lpChar^);{читаем символ}
  lpNull:=lpChar;{копируем адрес}
  lpByte:=lpNull;{копируем адрес}
  writeln(lpByte^);{выводим значение}
  {контрольный вывод}
  writeln('Control: ',chr(lpByte^),' = ',ord(lpChar^));
end.

2)Работа с массивами:
Код (Pascal) :: выделить код
type
  tA=array[1..5,1..5]of integer;{тип матрица 5х5}
  tB=array[1..10]of integer;{тип массив 10}
var
  pA:^tA;{указатель на матрицу}
  pB:^tB;{указатель на массив}
  i,j:integer;
{процедура вывода массива}
procedure Outmatrix(a:pointer;b,c:integer);
  var
    x,y:integer;
    z:^integer;{указатель на целый тип}
  begin
    z:=a;{копируем адрес}
    for x:=1 to b do{цикл по строкам}
      begin
        for y:=1 to c do{цикл по столбцам}
          begin
            write(z^:3);{вывод значения}
            inc(z);{переход к следующему целому}
          end;
        writeln;{переводим строку}
      end;
  end;
begin
  new(pA);{выделяем память под матрицу}
  for i:=1 to 5 do{цикл по строкам}
    for j:=1 to 5 do{цикл по столбцам}
      pA^[i,j]:=random(10);{заполняем матрицу}
  new(pB);{выделяем память под массив}
  for i:=1 to 10 do{цикл по массивам}
    pB^[i]:=random(10);{заполняем массив}
  writeln('Matrix A:');{выводим сообщение}
  OutMatrix(pA,5,5);{вывод матрицы}
  writeln('Matrix B:');{выводим сообщение}
  OutMatrix(pB,1,10);{вывод массива}
  readln;
  dispose(pA);{освобождаем память}
  dispose(pB);{освобождаем память}
end.

Удачи!

Консультировал: Зенченко Константин Николаевич (Модератор)
Дата отправки: 21.04.2016, 18:50
Рейтинг ответа:

НЕ одобряю 0 одобряю!


Оценить выпуск | Задать вопрос экспертам

главная страница  |  стать участником  |  получить консультацию
техническая поддержка  |  восстановить логин/пароль

Дорогой читатель!
Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались. Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора - для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение. Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал, который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом. Заходите - у нас интересно!
МЫ РАБОТАЕМ ДЛЯ ВАС!


В избранное