Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Универсальное объявление типа переменной.


Начинающий_1 ©   (2006-08-18 09:38:00) 

Допустим, есть следующие типы:
type
PArray2 = ^TArray2;
TArray2 = array[0..1] of integer;

PArray3 = ^TArray3;
TArray3 = array[0..2] of integer;

и функция:

function TestFunction(pArr: PArray2): integer;
var
i: integer;
begin
Result:=0;
for i:=Low(pArr) to High(pArr) do Result:=Result + pArr[i];
end;

Как бы сделать так, чтобы TestFunction могла принимать
в качестве параметра и PArray2 и PArray3 ?


Начинающий_1   (2006-08-19 09:00:00) [1]

Elen ©   (19.08.06 08:42) [13]
> Почему?
А вдруг я захочу изменить функцию Test так:
procedure Test(const ArrLen: Word; const pDist, pSour: Pointer);
var
i: integer;
begin
for i:=0 to ArrLen - 1 do
 if PArray1(pSour)[i] < pi
  then PArray1(pDist)[i]:=PArray1(pSour)[i]
  else PArray1(pDist)[i]:=47645;
end;


Elen   (2006-08-19 08:42:00) [2]


> Начинающий_1

Почему?


Начинающий_1   (2006-08-19 08:36:00) [3]

>Elen ©   (19.08.06 08:17) [11]
Неа. Не годится :))  CopyMemory тоже не годится. :)


Elen   (2006-08-19 08:17:00) [4]

А может проще так :
unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TForm1 = class(TForm)
   ListBox1: TListBox;
   procedure FormCreate(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;
type
PArray1 = ^TArray1;
TArray1 = array[0..0] of Double;

PArray637 = ^TArray637;
TArray637 = array[0..636] of Double;
var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var Dist, Sour : TArray637;
begin
move (sour,dist,sizeof(double)*637);
end;

end.


P.S. Просьба жестоко не пинать


Начинающий_1   (2006-08-19 05:50:00) [5]

Так будет правильно ?
type
PArray1 = ^TArray1;
TArray1 = array[0..0] of Double;

PArray637 = ^TArray637;
TArray637 = array[0..636] of Double;

procedure Test(const ArrLen: Word; const pDist, pSour: Pointer);
var
i: integer;
begin
for i:=0 to ArrLen - 1 do PArray1(pDist)[i]:=PArray1(pSour)[i];
end;

procedure TMainForm.ToolButton21Click(Sender: TObject);
var
Dist, Sour : TArray637;
begin
Test(637, @Dist, @Sour);
end;


Сергей М.   (2006-08-18 11:04:00) [6]

Это я для случая, если массивы различаются еще и типом элементов.
При этом  "изврат" работает лишь для стандартных базовых типов)


Сергей М.   (2006-08-18 11:01:00) [7]


> Elen ©   (18.08.06 10:55) [7]


Не только проще, но и желательно и удобно)

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


type
 PMyIntArray = ^TMyIntArray;
 TMyIntArray = array[0..0] of Integer;

 PMyDblArray = ^TMyDblArray;
 TMyDblArray = array[0..0] of Double;

 PMyStrArray = ^TMyStrArray;
 TMyStrArray = array[0..0] of String;

 PMyBoolArray = ^TMyBoolArray;
 TMyBoolArray = array[0..0] of Boolean;

 PArrayItem = pointer;

 function GetArrayItem(ItemType: Pointer; var MyArray; ItemIndex: Integer): PArrayItem;
 begin
   if ItemType = TypeInfo(Integer) then
     Result := @PMyIntArray(@MyArray)[ItemIndex]
   else if ItemType = TypeInfo(Double) then
     Result := @PMyDblArray(@MyArray)[ItemIndex]
   else if ItemType = TypeInfo(String) then
     Result := @PMyStrArray(@MyArray)[ItemIndex]
   else if ItemType = TypeInfo(Boolean) then
     Result := @PMyBoolArray(@MyArray)[ItemIndex]
 end;


Хотя иначе чем извращение это не назовешь)


Elen   (2006-08-18 10:55:00) [8]


> Сергей М.

А не проще воспользоваться типом Variant? или array of integer


Сергей М.   (2006-08-18 10:46:00) [9]

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

Достаточно объявить один-единственный массив

PMyArray = ^TMyArray;
TMyArray = array[0..0] of SomeType;

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


evvcom   (2006-08-18 10:38:00) [10]

См. как сделаны API-функции. Везде указатель и размер (как в [2]).


zdm   (2006-08-18 09:46:00) [11]

я имею ввиду что при обращении к функции ты пишешь примерно следующее
begin
TestFunction(PArray2)
end;
или
begin
TestFunction(PArray3)
end;
что подставишь то и будет,,,,а в самой функции лучше так одназанчо не определять, что это PArray2, чтобы не заблуждаться,,, если я туплю не ругайтесь.


clickmaker   (2006-08-18 09:44:00) [12]


> for i:=Low(pArr) to High(pArr)

у тебя это даже не скомпилится.
Представляешь себе, что такое указатель? И какой у него может быть Low и High?


zdm   (2006-08-18 09:42:00) [13]

в функции function TestFunction(pArr: PArray2): integer;
по моему по барабану само название "PArray2" кидай туда хоть qqq


Loginov Dmitry_   (2006-08-18 09:42:00) [14]


> Как бы сделать так, чтобы TestFunction могла принимать
> в качестве параметра и PArray2 и PArray3 ?


Тогда цикл  for i:=Low(pArr) to High(pArr)  работать не сможет.

Примерно следующее

function TestFunction(pArr: PIntegerArray, Size: Integer): integer;
var
  i: integer;
begin
  Result:=0;
  for i:=0 to Size - 1 do Result:=Result + pArr[i];
end;


Наверх

Титульная страница Поиск, карта сайта Написать письмо