Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Паскаль, Turbo Pascal, PascalABC.NET
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 24.08.2009, 21:26   #1
Mr.Qwerty
Что? Где? Когда?
Форумчанин
 
Аватар для Mr.Qwerty
 
Регистрация: 14.07.2009
Сообщений: 220
Печаль Никак не пойму смысл выражений

Начал учиться с самых что ни на есть истоков форума, вообщем копаю старые темы и разбираюсь в них, только вот никак не пойму это, хоть убейте:
Цитата:
Проблема решается с помощью использования динамической памяти.
Допустим нужно создать двумерный массив 200*300 типа integer;
он тебует 200*300*2=120000 байт для размещения.
Заведем массив нетипизированных указателей:

var A:array[1..200] of pointer;
выделим память под него

for i:=1 to 200 do GetMem(A[i],2*300); {2 байта-размер типа integer}

далее чтобы получить доступ конкретно к компонентам иассива нужно
вычислить адрес - [сегмент:смещение]

var RealPointer:^real;
i,j:integer;

RealPointer:=ptr(Seg(A[i]^),Ofs(A[i]^)+(j-1)*2)

здесь функция ptr() возвращает указатель (j-1)*2 - прибавка к смещению Ofs(A[i]^)
таким образом элемент [i,j] адресован.
Пробовал разобраться именно в
Цитата:
вычислить адрес - [сегмент:смещение]

var RealPointer:^real;
i,j:integer;

RealPointer:=ptr(Seg(A[i]^),Ofs(A[i]^)+(j-1)*2)
- вообще ничего не понял ( Помогите пожалуйста, опишите подробно что да как..! Буду очень благодарен!
Никогда не бойся делать то, что ты не умеешь. Помни, ковчег был построен любителем. Профессионалы построили "Титаник".
Mr.Qwerty вне форума Ответить с цитированием
Старый 24.08.2009, 23:19   #2
Daramant
Форумчанин
 
Регистрация: 06.01.2009
Сообщений: 340
По умолчанию

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

Ты знаком с таким понятием как динамическая память (куча)?
Если нет, почитай вот это:
http://thor.kubsu.ru/index.php/corpo...heskaya_pamyat

По коду:
Цитата:
вычислить адрес - [сегмент:смещение]
Доступ к ячейке памяти можно получить зная сегмент, в котором она находится и смещение внутри этого сегмента.
Цитата:
RealPointer:=ptr(Seg(A[i]^),Ofs(A[i]^)+(j-1)*2)
Здесь автор функцией Seg() получает адрес сегмента, в котором расположен массив, затем функцией Ofs() получает значение смещения внутри сегмента, по которому расположен первый элемент массива (или нулевой если считать с нуля), затем прибавляет к смещению некоторое значение: (j-1)*2, которое эквивалентно: Номер элемента * размер одного элемента массива, таким образом получая смещение j-го элемента, в конце функция ptr() возвращает указатель на этот j-элемент массива.

Что непонятно, спрашивай.

Теперь, как это реализовать проще:
Код:
program DynArray;

type
  TVal = Word; // тип элементов двумерного массива.
  P2DArray = ^T2DArray; // тип - указатель на массив.
  T2DArray = array[1..1, 1..1] of TVal; // тип - двумерный массив.

var
  My2DArrayPtr: P2dArray; // переменная - указатель
  RowCount, ColCount, Size: Word;
  i, j: Word;

begin
  RowCount := 2;
  ColCount := 4;
  // вычисляем размер массива
  // он равер "Количество строк" * "Количество столбцов" * "Размер одногоэлемента"
  Size := RowCount * ColCount * Sizeof(TVal); 
  // выделяем память под массив (размером 2 на 4)
  GetMem(My2DArrayPtr, Size);

  i := 2;
  j := 3;
  My2DArrayPtr^[i, j] := 3; // записываем значение в элемент [2, 3] массива
  writeln(My2DArrayPtr^[i, j]); // читаем значение из элемента [2, 3] массива

  // незабываем освободить память используемую память после работы.
  FreeMem(My2DArrayPtr, Size);
end.
Удачи.
Истинный успех – это то, что Вы сделали в сравнении с тем, что могли бы сделать.
Никогда не бойся делать то, что ты не умеешь. Помни, ковчег был построен любителем. Профессионалы построили "Титаник".
Daramant вне форума Ответить с цитированием
Старый 25.08.2009, 11:38   #3
Anatole
Форумчанин
 
Аватар для Anatole
 
Регистрация: 07.04.2009
Сообщений: 245
По умолчанию

Daramant
Цитата:
Теперь, как это реализовать проще:
Внешне оно проще, но вы забыли об условиях задачи:
Цитата:
Допустим нужно создать двумерный массив 200*300 типа integer;
он тебует 200*300*2=120000 байт для размещения.
Поскольку размерность массива больше 65535 байт(64К), то отвести память для него единым блоком в реальном режиме работы процессора невозможно. Данный пример был выбран специально для демонстрации доступа к динамической памяти и весьма эфектно демонстрирует доступ к физической памяти.
Всякое безобразие должно быть единообразным. Тогда это называется порядком.

Последний раз редактировалось Anatole; 25.08.2009 в 11:43.
Anatole вне форума Ответить с цитированием
Старый 25.08.2009, 11:41   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Anatole
Все равно автор явно сам запутался в том что написал...
По крайней мере действительно немного натянуто.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 25.08.2009, 12:12   #5
Anatole
Форумчанин
 
Аватар для Anatole
 
Регистрация: 07.04.2009
Сообщений: 245
По умолчанию

Stilet
Цитата:
По крайней мере действительно немного натянуто.
Полнрстью согласен. Сам никогда так бы не делал.
Mr.Qwerty
Поскольку строка предложенного массива меньше 64К (300*2=600) то логичнее общий двумерный массив представить в виде массива одномерных массивов. Приблизительно вот так:
Код:
Type
 Tar1 = array [1..300] of integer;
 Ptar1 = ^Tar1;(* Объявляем тип означающий адрес массива*)
var A:array[1..200] of pTar1; (*Массв адресов одномерных массивов*)
i : INTEGER;
begin
For i := 1 то 200 do GetMem(A[i],SizeOf(Tar1);(* отвоим в цикле памать на одномерные массивы*)
...
A[5]^[7] := 9; (*обращение к элементу A[5,7]*)
Writeln (A[5]^[7])
....
For i := 200 downto 1 do FreeMem(A[i], SizeOf(Tar1); (* освобождаем память, обязательно*)
end.
Всякое безобразие должно быть единообразным. Тогда это называется порядком.
Anatole вне форума Ответить с цитированием
Старый 25.08.2009, 20:54   #6
Daramant
Форумчанин
 
Регистрация: 06.01.2009
Сообщений: 340
По умолчанию

Цитата:
Поскольку размерность массива больше 65535 байт(64К), то отвести память для него единым блоком в реальном режиме работы процессора невозможно.
Anatole, в этом вы правы, я не обратил внимание, на то, что размер массива превышает размер одного сегмента.
Цитата:
Anatole
Код:
Type
 Tar1 = array [1..300] of integer;
 Ptar1 = ^Tar1;(* Объявляем тип означающий адрес массива*)
var A:array[1..200] of pTar1; (*Массв адресов одномерных массивов*)
Это пример верной реализации: просто и понятно.
Истинный успех – это то, что Вы сделали в сравнении с тем, что могли бы сделать.
Никогда не бойся делать то, что ты не умеешь. Помни, ковчег был построен любителем. Профессионалы построили "Титаник".

Последний раз редактировалось Daramant; 25.08.2009 в 20:57.
Daramant вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Задача в Delphi. Объясните смысл! Sianessa Помощь студентам 13 31.03.2009 22:11
В чем смысл жизни? NNN Свободное общение 76 14.07.2008 21:16
Никак не пойму где крыса затаилась! Подскажите! Хs-You Общие вопросы Delphi 12 19.08.2007 16:28