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

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

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 31.05.2009, 13:26   #1
SkAndrew
Форумчанин
 
Регистрация: 05.04.2008
Сообщений: 244
По умолчанию Как упростить конструкции Smallint(Pointer(@apeaks[i, 0])^) и PSmallInt(@apeaks[i, 1])^?

Добрый день!

Как можно упростить данный код (конструкции типа Smallint(Pointer(@apeaks[i, 0])^) и PSmallInt(@apeaks[i, 1])^) без изменения объявления глобальных переменных (массава apeaks : array of array of ^SmallInt)? И, пожалуйста объясните смысл этих конструкций (Smallint(Pointer(@apeaks[i, 0])^) и PSmallInt(@apeaks[i, 1])^).

Код:
var
  Form1: TForm1;
  apeaks : array of array of ^SmallInt;

implementation

uses Math;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
      var i : Integer;
begin
  Memo1.Lines.Clear;
  SetLength(apeaks, 0, 0);
  for i := 0 to 9 do
  begin
    SetLength(apeaks, i+1, 2);
    Smallint(Pointer(@apeaks[i, 0])^) := i - RandomRange(0, 32768);
    Smallint(Pointer(@apeaks[i, 1])^) := i - RandomRange(0, 32768);
    Memo1.Lines.Add(Format('%d. %d : %d; %d : %d', [i, b, c, SmallInt(Pointer(@apeaks[i, 0])^), PSmallInt(@apeaks[i, 1])^]));
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
      var i : Integer;
begin
  Memo2.Lines.Clear;
  for i := 0 to High(apeaks) do
  begin
    Memo2.Lines.Add(Format('%d. %d : %d', [i, SmallInt(Pointer(@apeaks[i, 0])^), SmallInt(@(apeaks[i, 1])^)])); //PSmallInt(@apeaks[i, 1])^]));
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Memo1.Lines.Clear;
  Memo2.Lines.Clear;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  SetLength(apeaks, 0, 0);
end;
Спасибо!
SkAndrew вне форума Ответить с цитированием
Старый 31.05.2009, 13:44   #2
BaronTreep
Форумчанин
 
Регистрация: 29.05.2009
Сообщений: 320
По умолчанию

А сам код работает?

Скорее всего нет...

указатели обычно используют так:

Код:
var
  x : integer;       // Просто целая
  px : ^integer;   // Указатель на целое
begin
   px := @x;      // теперь px указывает на содержание переменной x
   px^ := random(5);    // Присваиваем в x через px
end;

Последний раз редактировалось BaronTreep; 31.05.2009 в 14:01.
BaronTreep вне форума Ответить с цитированием
Старый 31.05.2009, 13:58   #3
Evgeniy26
Форумчанин
 
Аватар для Evgeniy26
 
Регистрация: 29.05.2009
Сообщений: 384
По умолчанию

Код:
  Setlength(apeaks, 1, 1);
  GetMem(apeaks[0, 0], SizeOf(SmallInt));
  apeaks[0, 0]^ := 5;
  FreeMem(apeaks[0, 0], SizeOf(SmallInt));
Код:
 
  Setlength(apeaks, 1, 1);
  New(apeaks[0, 0]);
  apeaks[0, 0]^ := 5;
  Dispose(apeaks[0, 0]);

Последний раз редактировалось Evgeniy26; 31.05.2009 в 14:10.
Evgeniy26 вне форума Ответить с цитированием
Старый 31.05.2009, 15:13   #4
SkAndrew
Форумчанин
 
Регистрация: 05.04.2008
Сообщений: 244
По умолчанию

Во-первых, спасибо за помощь.
Во-вторых код абсолютно рабочий, который я привел. можете проверить. значения в мемо 1 и 2 полностью совпадают. тоесть те значения который я заношу в массив я могу извлечь из него, например, в мемо 2.

Последний код интересный, но используя его так:

Код:
var
  Form1: TForm1;
  apeaks : array of array of ^SmallInt;
  b, c : SmallInt;

implementation

uses Math;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
      var i : Integer;
begin
  Memo1.Lines.Clear;
  if apeaks <> nil then
  begin
    SetLength(apeaks, 0, 0);
  end;
  for i := 0 to 9 do
  begin
    SetLength(apeaks, i+1, 2);
    GetMem(apeaks[i, 0], SizeOf(SmallInt));
    GetMem(apeaks[i, 1], SizeOf(SmallInt));
    b := i - RandomRange(0, 32768);
    c := i - RandomRange(0, 32768);
    // Smallint(Pointer(@apeaks[i, 0])^) := b;
    // Smallint(Pointer(@apeaks[i, 1])^) := c;
    apeaks[i, 0]^ := i - RandomRange(0, 32768);
    apeaks[i, 1]^ := i - RandomRange(0, 32768);
    Memo1.Lines.Add(Format('%d. %d : %d; %d : %d', [i, b, c, apeaks[i, 0]^, apeaks[i, 1]^])); // SmallInt(Pointer(@apeaks[i, 0])^), PSmallInt(@apeaks[i, 1])^]));
    FreeMem(apeaks[i, 0], SizeOf(SmallInt));
    FreeMem(apeaks[i, 1], SizeOf(SmallInt));
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
      var i : Integer;
begin
  Memo2.Lines.Clear;
  for i := 0 to High(apeaks) do
  begin
    Memo2.Lines.Add(Format('%d. %d : %d', [i, apeaks[i, 0]^, apeaks[i, 1]^])); // SmallInt(Pointer(@apeaks[i, 0])^), SmallInt(@(apeaks[i, 1])^)])); //PSmallInt(@apeaks[i, 1])^]));
  end;
end;
код работает, но я получаю отличные (разные) значения в мемо 1 и мемо 2 извлекая из массива и сравниваая с исходными, которые вношу в массив (b и с). Что неверно? может по другому нужно как-то извлекать из такого массива данныее? Спасибо

Последний раз редактировалось SkAndrew; 31.05.2009 в 15:19.
SkAndrew вне форума Ответить с цитированием
Старый 31.05.2009, 15:48   #5
Evgeniy26
Форумчанин
 
Аватар для Evgeniy26
 
Регистрация: 29.05.2009
Сообщений: 384
По умолчанию

Вы память очищаете.
Код:
FreeMem(apeaks[i, 0], SizeOf(SmallInt));
FreeMem(apeaks[i, 1], SizeOf(SmallInt));
А потом запрашиваете. Конечно там мусор будет.
Evgeniy26 вне форума Ответить с цитированием
Старый 31.05.2009, 16:09   #6
SkAndrew
Форумчанин
 
Регистрация: 05.04.2008
Сообщений: 244
По умолчанию

Тогда правильно перед каждым нажатие кнопки будет так или что-то снова неверно?
то есть как правильно обновлять массив, при этом не создавая мусор или не оставляя мусор в памяти, а тоже ее очищая.

Код:
procedure TForm1.Button1Click(Sender: TObject);
      var i : Integer;
begin
  Memo1.Lines.Clear;
  if apeaks <> nil then
  begin
    for i := 0 to High(apeaks) do
    begin
      FreeMem(apeaks[i, 0], SizeOf(SmallInt));
      FreeMem(apeaks[i, 1], SizeOf(SmallInt));
    end;
  end;
  SetLength(apeaks, 0, 0);
  for i := 0 to 9 do
  begin
    SetLength(apeaks, i+1, 2);
    GetMem(apeaks[i, 0], SizeOf(SmallInt));
    GetMem(apeaks[i, 1], SizeOf(SmallInt));
    b := i - RandomRange(0, 32768);
    c := i - RandomRange(0, 32768);
    apeaks[i, 0]^ := b; // i - RandomRange(0, 32768);
    apeaks[i, 1]^ := c; // i - RandomRange(0, 32768);
    Memo1.Lines.Add(Format('%d. %d : %d; %d : %d', [i, b, c, apeaks[i, 0]^, apeaks[i, 1]^]));
end;
Спасибо

Последний раз редактировалось SkAndrew; 31.05.2009 в 16:15.
SkAndrew вне форума Ответить с цитированием
Старый 31.05.2009, 16:23   #7
Evgeniy26
Форумчанин
 
Аватар для Evgeniy26
 
Регистрация: 29.05.2009
Сообщений: 384
По умолчанию

Код:
var 
  i : Integer;
begin
  Memo1.Lines.Clear;
  if apeaks <> nil then
    for i := 0 to High(apeaks) do
    begin
      Dispose(apeaks[i, 0]);
      Dispose(apeaks[i, 1]);
    end;
  SetLength(apeaks, 10, 2);
  for i := 0 to High(apeaks) do
  begin
    New(apeaks[i, 0]);
    New(apeaks[i, 1]);
    b := i - RandomRange(0, 32768);
    c := i - RandomRange(0, 32768);
    apeaks[i, 0]^ := b; // i - RandomRange(0, 32768);
    apeaks[i, 1]^ := c; // i - RandomRange(0, 32768);
    Memo1.Lines.Add(Format('%d. %d : %d; %d : %d', [i, b, c, apeaks[i, 0]^, apeaks[i, 1]^]));
  end;
И в обработчик OnClose формы вставте
Код:
   if apeaks <> nil then
    for i := 0 to High(apeaks) do
    begin
      Dispose(apeaks[i, 0]);
      Dispose(apeaks[i, 1]);
    end;

Последний раз редактировалось Evgeniy26; 31.05.2009 в 16:32.
Evgeniy26 вне форума Ответить с цитированием
Старый 31.05.2009, 18:47   #8
SkAndrew
Форумчанин
 
Регистрация: 05.04.2008
Сообщений: 244
По умолчанию

Спасибо большое за очень подробную помощь.
Если не сложно можно еще вопрос:

В каких случаях лучше использовать New, а в каких GetMem и что должно идти раньше - обявление размера массива SetLength(apeaks, i+1, 2);, а затем выделение памяти New или GetMem или наоборот. Соответственно, правилная конструкция сперва высвобождения памти, а потом SetLength(apeaks, 0, 0); или как-то иначе.

Спасибо еще раз!
SkAndrew вне форума Ответить с цитированием
Старый 31.05.2009, 19:09   #9
Evgeniy26
Форумчанин
 
Аватар для Evgeniy26
 
Регистрация: 29.05.2009
Сообщений: 384
По умолчанию

Найдите там главу указатели: http://www.delphikingdom.com/asp/vie...catalogID=1184
Поищите, информации на эту тему много.
Evgeniy26 вне форума Ответить с цитированием
Старый 01.06.2009, 09:45   #10
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
В каких случаях лучше использовать New, а в каких GetMem
New удобнее. Это скорее директива чем функция. Она просит память согласно размеру переменки, а GetMem выделяет побайтно, и даже если ты попросишь больше или меньше чем нужно для переменки она сработает.
Я бы cказал New универсальнее...
I'm learning to live...
Stilet вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Чтение из файла smallint Лурье Общие вопросы Delphi 7 13.05.2009 18:45
как выделить память для указателя (pointer), и сюда же, записать : integer, потом через 4 байта, boolean? bigxman Общие вопросы Delphi 1 02.02.2009 21:17
Вопрос по конструкции if() С++ ROD Помощь студентам 2 20.12.2008 20:14
вопрос по использованию конструкции if zetrix Microsoft Office Excel 0 31.10.2006 07:52