![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Динамические массивы - правильно ли я понял help?
Ega23 © (2005-06-01 14:41:00)Никогда не работал с дин.массивами. Хочется узнать - правильно ли я понял, как с ними работать?
Допустим:
var
a:array of Integer;
begin
SetLength(a, 5); // в массиве 5 элементов.
a[0]:=1; a[4]:5; // Индексация в массиве - с 0 до Length(a)-1
SetLength(a, 6); // Сохранились ли предыдущие значения a[0] и a[4]?
SetLength(a, 0) // Опреация по освобождению массива
end;
Так ли это?
Ega23 (2005-06-01 17:21:00) [41]
> a: packed array of тип_элемента
Спасибо. Это ценная информация.
Для статических массивов при описании структуры я packed использую, но про динамические - не знал.
Юрий Зотов (2005-06-01 16:54:00) [42]> Ega23 © (01.06.05 14:52) [5]
Чтобы использовать что-то типа
ReadBuffer(a[0], Length(a) * SizeOf(тип_элемента))
массив, строго говоря, должен быть объявлен так:
a: packed array of тип_элемента
Тут этот вопрос когда-то обсуждался и выяснилось, что компилятор пакует массивы даже и при отсутствии packed, но я бы все же рекомендовал указывать packed явно. Как минимум, по трем причинам:
- гарантирует от возможных коллизий в будущих версиях;
- дисциплинирует мозги;
- код становится прозрачнее.
Ega23 (2005-06-01 15:36:00) [43]Откровенно говоря, когда в университете проходили списки и способы их построения, всяческими array of и TList при написании заданий пользоваться было категорически запрещено.
Ну, TList я с тех пор худо-бедно освоил :)
А вот с массивами как-то не срослось. Да и надобности не было...
evvcom (2005-06-01 15:05:00) [44]
> только без GetMem - FreeMem
зато с (+) Length, Low и High, хотя для дин.массивов Low всегда = 0
evvcom (2005-06-01 15:02:00) [45]
> А почему a[0]?
Потому что procedure ReadBuffer(var Buffer; Count: Longint);
Передаешь a[0] по ссылке, компилятор подставляет адрес 0-го элемента, если передавать a, то передашь адрес переменной a-указателя на динамический массив.
Ega23 (2005-06-01 15:02:00) [46]Ага, спасибо. В общем, всё также, как и в "ручном" формировании динамического массива, только без GetMem - FreeMem
begin...end (2005-06-01 15:01:00) [47]> КаПиБаРа © (01.06.05 14:59) [9]
> a[0] - адрес первого элемента массмива
a[0] -- это не адрес. Это сам элемент.
КаПиБаРа (2005-06-01 14:59:00) [48]Ega23 © (01.06.05 14:57) [7]
Так нада.
a[0] - адрес первого элемента массмива
a - адрес где храится сцылка на a[0]
begin...end (2005-06-01 14:59:00) [49]> Ega23 © (01.06.05 14:57) [7]
Потому что иначе (как в коде [5]) ты будешь читать не в область, в которой расположены элементы массива, а в указатель на эту область.
Ega23 (2005-06-01 14:57:00) [50]А почему a[0]?
Amoeba (2005-06-01 14:54:00) [51]ms.ReadBuffer(a[0], Count*SizeOf(Integer));
Ega23 (2005-06-01 14:52:00) [52]Вдогонку ещё один вопрос:
Могу ли я после задания длины массиву (SetLength(a, Count)) использовать переменную a в виде буфера при чтении из Stream?
var
a:array of integer;
Count:Integer;
ms:TMemoryStream;
begin
ms:=TMemoryStream.Create;
try
TBLOBField(Query1.FieldByName('Data')).SaveToStream(ms);
Count:=Query1.FieldByName('DataLength').AsInteger;
ms.Position:=0;
SetLength(a, Count);
ms.ReadBuffer(a, Count*SizeOf(Integer));
......
finally
ms.Free;
a:=nil;
end;
end;
Ega23 (2005-06-01 14:46:00) [53]Спасибо всем.
Юрий Зотов (2005-06-01 14:45:00) [54]> в массиве 5 элементов.
Да.
> Индексация в массиве - с 0 до Length(a)-1
Да. Еще можно использовать Low(a) и High(a).
> Сохранились ли предыдущие значения a[0] и a[4]?
Да. Сохранились вообще все элементы, включая и мусорные.
> Опреация по освобождению массива
Либо так, либо a := nil.
begin...end (2005-06-01 14:43:00) [55]> Ega23 © (01.06.05 14:41)
> Сохранились ли предыдущие значения a[0] и a[4]?
Да.
> Опреация по освобождению массива
Если это уже конец подпрограммы, то это делать необязательно. Дин. массив освободится автоматически пр выходе из области видимости.
TUser (2005-06-01 14:43:00) [56]Все правильно. Элементы 0-4 сохранятся. + хорохо бы еще finally поставить.
Hint: Если массив объявлен как локальная переменная, то Delphi гарантирует освобождение памяти по завершении работы процедуры.