Вопросы и ответы - Delphi - Массивы в Delphi - Библиотека программиста
Пользователь

Добро пожаловать,

Регистрация или входРегистрация или вход
Потеряли пароль?Потеряли пароль?

Ник:
Пароль:

Меню сайта




Ваше мнение
Каким поисковиком вы пользуетесь ?

Google.ru
Google.com
Rambler
Mail.ru
WebAlta
Яндекс
Апорт
Yahoo
Gogo.ru
Другим


Результаты
Другие опросы

Всего голосов: 1715
Комментарии: 4


Наши партнеры



Статистика




Programming books  Download software  Documentation  Scripts  Content Managment Systems(CMS)  Templates  Icon Sets  Articles  Contacts  Voting  Site Search




Вопросы и ответы - Delphi - Массивы в Delphi

                  
 
Array --> String
Код
function ArrayToStr(str: TStrings; r: string): string;

var

i: integer;

begin

Result:='';

if str = nil then

Exit;

for i := 0 to Str.Count-1 do

Result := Result + Str.Strings[i] + r;

end;
Array of Byte --> TMemoryStream
Код
procedure TForm1.Button2Click(Sender: TObject);

const

Start = 49;

AnEnd = 57;

ArLen = AnEnd - Start + 1;

var

M: TMemoryStream;

Buff: array of Byte;

I: Integer;

begin

SetLength(Buff, ArLen);

for I := 0 to ArLen - 1 do

Buff[I] := Start + I;



M := TMemoryStream.Create;

try

M.Write(Buff[0], ArLen);

M.SaveToFile('c:test.txt');

finally

M.Free;

end;

end;



В результате должен получится файл c:test.txt такого содержания:

123456789


поскольку числа с 49 до 51 являются ASCII-кодами этих чисел, а соответственно и являются их символьным представлением.

String --> Array
Код
Procedure AssignFixedString( Var FixedStr: Array of Char; Const S: String

);

Var

maxlen: Integer;

Begin

maxlen := Succ( High( FixedStr ) - Low( FixedStr ));

FillChar( FixedStr, maxlen, ' ' ); { blank fixed string }

If Length(S) > maxlen Then

Move( S[1], FixedStr, maxlen )

Else

Move( S[1], FixedStr, Length(S));

End;



Еще вариант:

Код
function StrToArrays(str, r: string; out Temp: TStrings): Boolean;

var

j: integer;

begin

if temp <> nil then

begin

temp.Clear;

while str <> '' do

begin

j := Pos(r,str);

if j=0 then

j := Length(str) + 1;

temp.Add(Copy(Str,1,j-1));

Delete(Str,1,j+length(r)-1);

end;

Result:=True;

end

else

Result:=False;

end;

TMemoryStream --> Array of Byte
Для преобразования TMemoryStream в array of Byte можно использовать следующий код:

Код
procedure TForm1.Button1Click(Sender: TObject);

var

M: TMemoryStream;

Buff: array of Byte;

begin

M := TMemoryStream.Create;

try

M.LoadFromFile('c:test.htm');

SetLength(Buff, M.Size);

M.Position := 0;

M.Read(Buff[0], M.Size);

finally

M.Free;

end;

end;
Запись массива на диск
Скажем, ваша структура данных выглядит следующим образом:

Код
type

TMyRec = record

SomeField: Integer;

SomeOtherField: Double;

TheRest: array[0..99] of Single;

end;



и TBlobField имеет имя MyBlobField. TMyRec назван как MyRec. Для копирования содержимого MyRec в MyBlobField необходимо сделать следующее:

Код
var

Stream: TBlobStream;

begin

Stream := TBlobStream.Create(MyBlobField, bmWrite);

Stream.Write(MyRec, SizeOf(MyRec));

Stream.Free;

end;



Есть другой путь:

Код
var

Stream: TBlobStream;

begin

Stream := TBlobStream.Create(MyBlobField, bmRead);

Stream.Read(MyRec, SizeOf(MyRec));

Stream.Free;

end;
Использование DynArrayFromVariant
Код
procedure TForm1.Button1Click(Sender: TObject);

type

T2DIntArray = array of array of Integer;

var

DynArray: T2DIntArray;

V: Variant;

i, k: Integer;

begin

V := VarArrayCreate([0, 1, 0, 1], varInteger);

V[0, 0] := 00;

V[0, 1] := 01;

V[1, 0] := 10;

V[1, 1] := 11;

DynArrayFromVariant(Pointer(Dynarray), V, TypeInfo(T2DIntArray));

for i := 0 to High(Dynarray) do

for k := 0 to High(Dynarray[i]) do

memo1.Lines.add(IntToStr(DynArray[i, k]));

end;



{

The problem with DynArrayFromVariant is that you can only use it on

variant arrays with 0-based indexes, trying to use it on an array with 1

as lower bound blows up. Since the documentation is silent on that i

would consider it a bug.

}
Использование PHP-like операций с массивами
Код
type



ArrOfStr = array of string;



implementation



function explode(sPart, sInput: string): ArrOfStr;

begin

while Pos(sPart, sInput) <> 0 do

begin

SetLength(Result, Length(Result) + 1);

Result[Length(Result) - 1] := Copy(sInput, 0,Pos(sPart, sInput) - 1);

Delete(sInput, 1,Pos(sPart, sInput));

end;

SetLength(Result, Length(Result) + 1);

Result[Length(Result) - 1] := sInput;

end;



function implode(sPart: string; arrInp: ArrOfStr): string;

var

i: Integer;

begin

if Length(arrInp) <= 1 then Result := arrInp[0]

else

begin

for i := 0 to Length(arrInp) - 2 do Result := Result + arrInp[i] + sPart;

Result := Result + arrInp[Length(arrInp) - 1];

end;

end;



procedure sort(arrInp: ArrOfStr);

var

slTmp: TStringList;

i: Integer;

begin

slTmp := TStringList.Create;

for i := 0 to Length(arrInp) - 1 do slTmp.Add(arrInp[i]);

slTmp.Sort;

for i := 0 to slTmp.Count - 1 do arrInp[i] := slTmp[i];

slTmp.Free;

end;



procedure rsort(arrInp: ArrOfStr);

var

slTmp: TStringList;

i: Integer;

begin

slTmp := TStringList.Create;

for i := 0 to Length(arrInp) - 1 do slTmp.Add(arrInp[i]);

slTmp.Sort;

for i := 0 to slTmp.Count - 1 do arrInp[slTmp.Count - 1 - i] := slTmp[i];

slTmp.Free;

end;
Использование ассоциативных массивов
Код
procedure TForm1.Button1Click(Sender: TObject);

var

DataField: TStrings;

begin

DataField := TStringList.Create;

DataField.Add(Format('%s=%s', ['Jonas', '15.03.1980']));

ShowMessage(DataField.Values['Jonas'])

// will print the Birthday of Jonas

DataField.Free;

end;
Использование многомерного массива
Код
type RecType = integer; {<-- здесь задается тип элементов массива}

const MaxRecItem = 65520 div sizeof(RecType);

type = MyArrayType = array[0..MaxRecItem] of RecType;

type = MyArrayTypePtr = ^MyArrayType;

var MyArray: MyArrayTypePtr;

begin

ItemCnt := 10; {количество элементов массива, которые необходимо распределить}

GetMem(MyArray, ItemCnt * sizeof(MyArray[1])); {распределение массива}

MyArray^[3] := 10; {доступ к массиву}

FreeMem(MyArray, ItemCnt * sizeof(MyArray[1])); {освобождаем массив после работы с ним}

end;
Как передать массив как параметр?
Передача параметров процедуры и функции в дельфи:

Код
Type Ta=array of something;

Var a:Ta;



Вариант 1.

Код
Procedure Proc(a:Ta);



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


Вариант 2.

Код
Procedure Proc(var a:Ta);



внутри процедуры код работает именно с переменной а и её содержимым


Вариант 3.

Код
Procedure Proc(const a:Ta);



внутри процедуры запрещено изменять данные переменной а


Вариант 4.

Код
Procedure Proc(out a:Ta);



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

Как поместить двумерный массив в Image
Представим, что данные находятся в массиве:

Код
TestArray : array[0..127, 0..127] of Byte;



Картинка будет иметь размер 128 x 128 точек:

Код
Image1.Picture.Bitmap.Width := 128;
Image1.Picture.Bitmap.Height := 128;



Вызываем функцию Windows API для формирования BitMap:

Код
SetBitmapBits(Image1.Picture.Bitmap.Handle, sizeof(TestArray), @TestArray);

Image1.Refresh; {для того, чтобы изменения отобразились}



Однако, если вы используете свою палитру, то ее нужно создать.
Массив Edit-компонентов
Код
procedure DoSomethingWithEditControls;

var

K: Integer;

EditArray: array[0..99] of Tedit;

begin

try

for K := 0 to 99 do

begin

EditArray[K] := TEdit.Create(Self);

EditArray[K].Parent := Self;

{Устанавливаем необходимые свойства TEdit}

SetSomeOtherPropertiesOfTEdit;

Left := 100;

Top := K * 10;

{Что-то делаем при перемещении мыши}

OnMouseMove := WhatToDoWhenMouseIsMoved;

end;

{Делаем все что хотим с полученным массивом Edit-компонентов}

DoWhateverYouWantToDoWithTheseEdits;

finally

for K := 0 to 99 do

EditArray[K].Free;

end;

end;

Массив без ограничения типа и размера
Код
//к примеру опишем свой тип

type



MyType = record

zap1: longword;

zap2: char;

zap3: string[10];

end;



//опишем НЕОГРАНИЧЕННЫЙ массив переменный типа MyType

//хотя, может использоваться абсолютно любой

var

m: array of MyType;



....



procedure TForm1.Button1Click(Sender: TObject);

var i: byte;

begin

for i := 0 to 9 do // нумерация элементов начинается с нуля!



begin

SetLength(m, Length(m) + 1); // увеличение длины массива на 1

m[i].zap1 := i; // присвоение

m[i].zap2 := chr(i); // полям

m[i].zap3 := inttostr(i); // значений

end;

end;



....



SetLength(m, 0); // освобождение памяти

end.
Массив в Delphi
Вот несколько функций для операций с двухмерными массивами. Самый простой путь для создания собственной библиотеки. Процедуры SetV и GetV позволяют читать и сохранять элементы массива VArray (его Вы можете объявить как угодно). Например:

Код
type

VArray: array[1..1] of double;



var

X: ^VArray;

NR, NC: Longint;



begin

NR := 10000;

NC := 100;

if AllocArray(pointer(X), N * Sizeof(VArray)) then exit;

SetV(X^, NC, 2000, 5, 3.27); { X[2000,5] := 3.27 }

end;



function AllocArray(var V: pointer; const N: longint): Boolean;

begin {распределяем память для массива V размера N}

try

GetMem(V, N);

except

ShowMessage('ОШИБКА выделения памяти. Размер:' + IntToStr(N));

Result := True;

exit;

end;

FillChar(V^, N, 0); {в случае включения длинных строк заполняем их нулями}

Result := False;

end;



procedure SetV(var X: Varray; const N, ir, ic: LongInt; const value:

double);

begin {заполняем элементами двухмерный массив X размером ? x N : X[ir,ic] := value}



X[N * (ir - 1) + ic] := value;

end;



function GetV(const X: Varray; const N, ir, ic: Longint): double;

begin {возвращаем величины X[ir,ic] для двухмерного массива шириной N столбцов}

Result := X[N * (ir - 1) + ic];

end;
Массив компонентов
Возможно ли создание массива компонентов? Для показа статуса я использую набор LED-компонентов и хотел бы иметь к ним доступ, используя массив.

Прежде всего необходимо объявить массив:
Код
{10 элементов компонентного типа TLed}
LED : array[1..10] of TLed;


При необходимости динамического создания LED-компонентов организуйте цикл, пример которого мы приводим ниже:
Код
for counter := 1 to 10 do

begin

LED[counter]:= TLED.Create;

LED[counter].top := ...

LED[counter].Left := ...

LED[counter].Parent := Mainform; {что-то типа этого}

end;


Если компоненты уже присутствуют на форме (в режиме проектирования), сделайте их элементами массива, например так:
Код
leds := 0;

for counter := 0 to Form.Componentcount do

begin

if (components[counter] is TLED) then

begin

inc(leds);

LED[leds] := TLED(components[counter]);

end

end;


Тем не менее у нас получился массив со случайным расположением LED-компонентов. Я предлагаю назначить свойству Tag каждого LED-компонента порядковый номер его расположения в массиве, а затем заполнить массив, используя это свойство:
Код
for counter := 0 to Form.Componentcount do

begin

if (components[counter] is TLED) then

begin

LED[Component[counter].tag] := TLED(components[counter]);

end

end;


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

Операции над числовыми массивами
  • MaxIntValue Возвращает наибольшее значение целочисленного массива.
  • MaxValue Возвращает наибольшее значение числового массива.
  • Mean Вычисляет среднее арифметическое всех значений массива.
  • MeanAndStdDev Вычисляет среднее арифметическое всех значений массива, и среднее отклонение.
  • MinIntValue Возвращает наименьшее значение целочисленного массива.
  • MinValue Возвращает наименьшее значение числового массива.
  • MomentSkewKurtosis Вычисляет среднее значение, дисперсию, отклонение и периодичность.
  • Norm Возвращает Евклидову норму для всех значений массива.
  • PopnStdDev Вычисляет среднеквадратичное отклонение для совокупности данных.
  • PopnVariance Вычисляет дисперсию совокупности данных.
  • StdDev Вычисляет стандартное среднеквадратичное отклонение элементов массива.
  • Sum Вычисляет сумму значений всех элементов числового массива.
  • SumInt Вычисляет сумму значений всех элементов целочисленного массива.
  • SumOfSquares Вычисляет сумму квадратов всех элементов числового массива.
  • SumsAndSquares Возвращает сумму элементов и сумму квадратов всех элементов числового массива.
  • TotalVariance Вычисляет статистическую дисперсию.
  • Variance Вычисляет типовую дисперсию всех значений массива.

  • Поиск минимального элемента массива
    Код
    unit lookmin_;



    interface



    uses

    Windows, Messages, SysUtils, Classes, Graphics,

    Controls, Forms, Dialogs, StdCtrls, Grids;



    type

    TForm1 = class(TForm)

    Label1: TLabel;

    Button1: TButton;

    Label2: TLabel;

    StringGridl: TStringGrid;

    procedure ButtonlClick(Sender: TObject);

    private

    { Private declarations }

    public

    { Public declarations }

    end;



    var

    Form1: TForm1;



    implementation

    {$R *.DFM}





    procedure TForm1.ButtonlClick(Sender: TObject);

    const

    SIZE = 5;

    var

    a: array[l..SIZE] of integer; // массив целых

    min: integer; // номер минимального элемента массива

    i: integer; // номер элемента, сравниваемого с минимальным

    begin

    // ввод массива for i:=1 to SIZE do

    a[i] := StrToInt(StringGridl.Cells[i - 1, 0]);

    // поиск минимального элемента

    min := 1; // пусть первый элемент минимальный

    for i := 2 to SIZE do

    if a[i] < a[min] then

    min := i;

    // вывод результата

    label2.caption := 'Минимальный элемент массива:'

    + IntToStr(a[min] + #13 + 'Номер элемента:' + IntToStr(min);

    end;



    end.
    Пример массива констант (Array of Const)
    "Array of const" это массив переменных, декларированных как константы. Массив констант (array of const) фактически является открытым массивом TVarRec (описание предекларированных типов Delphi вы можете найти в электронной справке). Приведенный ниже "псевдокод" на языке Object Pascal может послужить скелетом для дальнейшего развития:

    Код
    procedure AddStuff(const A: array of const);

    var i: Integer;

    begin

    for i := Low(A) to High(A) do

    with A do

    case VType of

    vtExtended:

    begin

    { добавляем натуральное число, все real-форматы

    автоматически приводятся к extended }

    end;

    vtInteger:

    begin



    { добавляем целое число, все integer-форматы

    автоматически приводятся к LongInt }

    end;

    vtObject:

    begin

    if VObject is DArray then

    with DArray(VObject) do

    begin

    { добавляем массив double-типа }

    end

    else if VObject is IArray then

    with IArray(VObject) do

    begin

    { добавляем массив integer-типа }

    end;

    end;

    end; { Case }

    end; { AddStuff }


    [i]
  • Для получения дополнительной информации загляните в главу "open arrays" электронной справки.





  • Примеры работы с динамическими массивами
    Код
    const

    MaxBooleans = (High(Cardinal) - $F) div sizeof(boolean);



    type

    TBoolArray = array[1..MaxBooleans] of boolean;

    PBoolArray = ^TBoolArray;



    var

    B: PBoolArray;

    N: integer;



    begin

    N := 63579;

    {= получение памяти под динамический массив.. =}

    GetMem(B, N * sizeof(boolean));

    {= работа с массивом... =}

    B^[3477] := FALSE;

    {= возвращение памяти в кучу =}

    {$IFDEF VER80}

    FreeMem(B, N * sizeof(boolean));

    {$ELSE}

    FreeMem(B);

    {$ENDIF}

    end.



    Ниже приведен пример динамического массива:

    Код
    unit Unit1;



    interface



    uses

    SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics,

    Controls, Forms, Dialogs, StdCtrls;



    type

    ElementType = Integer;



    const

    MaxArraySize = (65520 div SizeOf(ElementType));

    { в 16-битной среде }



    type

    { Создаем тип массива. Убедитесь в том, что вы установили

    максимальный диапазон, который вам, вероятно, может понадобиться. }

    TDynamicArray = array[1..MaxArraySize] of ElementType;

    TForm1 = class(TForm)

    Button1: TButton;

    procedure FormCreate(Sender: TObject);

    procedure Button1Click(Sender: TObject);

    procedure FormDestroy(Sender: TObject);

    private

    { Private declarations }

    public

    { Public declarations }

    end;



    var

    Form1: TForm1;

    { Создаем переменную типа указатель на ваш тип массива. }

    P: ^TDynamicArray;



    const

    { Это типизированные константы. В действительности они

    являются статическими переменными, инициализирующимися

    во время выполнения указанными в исходном коде значениями.

    Это означает, что вы можете использовать типизированные

    константы точно также, как и любые другие переменные.

    Удобство заключается в автоматически инициализируемой величине. }

    DynamicArraySizeNeeded: Integer = 10;



    implementation



    {$R *.DFM}



    procedure TForm1.FormCreate(Sender: TObject);

    begin

    { Распределяем память для нашего массива. Будь внимательны

    и распределяйте размер, в точности необходимый для размещения нового массива.

    Если вы попытаетесь записать элемент, выходящий за допустимый диапазон,

    компилятор не ругнется, но объект исключения вам обеспечен. }

    DynamicArraySizeNeeded := 500;

    P := AllocMem(DynamicArraySizeNeeded * SizeOf(Integer));

    { Как присвоить значение пятому элементу массива. }

    P^[5] := 68;

    end;



    procedure TForm1.Button1Click(Sender: TObject);

    begin

    { Вывод данных. }

    Button1.Caption := IntToStr(P^[5]);

    end;



    procedure TForm1.FormDestroy(Sender: TObject);

    begin

    { Освобождаем распределенную для массива память. }

    FreeMem(P, DynamicArraySizeNeeded * SizeOf(Integer));

    end;



    end.
    Проверка наличия числа в массиве
    Код
    function Among(N: Integer; const Values: array of Integer): LongBool;

    asm

    push ebx

    xor ebx, ebx

    @@10:

    test ecx, ecx

    jl @@30

    cmp eax, [edx]

    jne @@20

    not ebx

    jmp @@30

    @@20:

    add edx, 4

    dec ecx

    jmp @@10

    @@30:

    mov eax, ebx

    pop ebx

    end;

    Пример использования:



    Among(N, [1, 2, 3, 4, 5])



    Печать страницы
    Печать страницы




    Внимание! Если у вас не получилось найти нужную информацию, используйте рубрикатор или воспользуйтесь поиском


    .



    книги по программированию исходники компоненты шаблоны сайтов C++ PHP Delphi скачать