Форум: "Начинающим";
Текущий архив: 2009.11.08;
Скачать: [xml.tar.bz2];
Внизarray [0..0] of ... Найти похожие ветки
← →
Прима (2009-09-18 12:49) [0]
type
TElem = packed record
S1:Byte;
S2:Byte;
D1:DWord;
end;
TMArr = array [0..0] of TElem;
TFuck = record
B:Byte;
Q:TMArr;
end;
procedure TForm1.Button1Click(Sender: TObject);
var Q:TFuck;
I:Integer;
begin
Q.B:=1;
Q.Q[0].S1:=1;
Q.Q[0].S2:=1;
Q.Q[0].D1:=1;
Q.Q[1].S1:=2; <=Constant expression violates subrange bounds
Q.Q[1].S2:=2;
Q.Q[1].D1:=2;
//
for I:=0 to Length(Q.Q)-1 do
begin
Memo1.Lines.Add(Format("%d %d",[Q.Q[I].S1, Q.Q[I].S2]));
end;
end;
В чем я не прав ? Необходимо заранее указывать размер массива?
Тогда как ?
Спасибо !
← →
Прима (2009-09-18 12:54) [1]
Q.B:=1;
SetLength(Q.Q,2); <=Incompatible types
Q.Q[0].S1:=1;
← →
Прима (2009-09-18 12:56) [2]Пардон. Разобрался.
Вот решение :TMArr = array of TElem;
← →
Юрий Зотов © (2009-09-18 13:01) [3]> Прима (18.09.09 12:49)
> Необходимо заранее указывать размер массива?
Размер статического массива указывается при его объявлении и не может быть изменен. Вы объявили статисеский массив, который содержит один элемент с индексом 0, поэтому Q.Q[1] дает ошибку.
> Тогда как ?
Используйте либо динамический массив (см. в справке Dynamic arrays), либо указатель на статический массив (сначала выделив под него память, конечно). Первый способ, похоже, будет проще.
← →
Прима (2009-09-18 13:18) [4]2 Юрий Зотов © (18.09.09 13:01) [3]
Спасибо
.
> либо указатель на статический массив (сначала выделив под
> него память, конечно).
Хочу разобраться для себя. Можно подробнее и кодом ?GetMem(Q.Q,SizeOf(TElem)*2);
Ибо даже выделить память пока не получается
← →
Anatoly Podgoretsky © (2009-09-18 13:24) [5]
> Прима (18.09.09 13:18) [4]
Для статических массивов память тоже выделяется статически, через указание размерности в типа.
← →
Прима (2009-09-18 13:26) [6]2 Anatoly Podgoretsky © (18.09.09 13:24) [5]
> Для статических массивов память тоже выделяется статически,
> через указание размерности в типа.
Пардон, но я не понял. Можно ли кодом ?
← →
Anatoly Podgoretsky © (2009-09-18 13:30) [7]Можно
> TMArr = array [1..11] of TElem;
Вот тут выделена память по 11 элементов типа TElem
← →
Прима (2009-09-18 13:35) [8]Это понятно.
Я хочу для себя разобраться как работать с [0..0]
Насколько я понимаю, нужно завести новую переменную. И указать ей размер будующего массива. А далее не понятно.
var P:Pointer;
begin
GetMem(P,SizeOf(TElem)*2);
Q.Q сопоставить с P как-то
← →
Anatoly Podgoretsky © (2009-09-18 13:41) [9]> Прима (18.09.2009 13:35:08) [8]
Работать с [0..0] идеологически неправильно, работай с [0..MaxInt]
← →
Anatoly Podgoretsky © (2009-09-18 13:44) [10]P: ^TMArr;
Но в наше время нужды в этом нет, начиная с Д4 есть динамические массивы.
← →
Юрий Зотов © (2009-09-18 14:07) [11]> Прима (18.09.09 12:49)
type
TElem = packed record
S1:Byte;
S2:Byte;
D1:DWord;
end;
PElem = ^TElem
TMArr = packed array [0..0] of TElem;
PMArr = ^TMArr;
TRec = record
B: Byte;
Q: PMArr;
end;
function GetElem(R: TRec, Index: integer): TElem;
begin
Result := PElem(Cardinal(R.Q) + Index * SizeOf(TElem))^
end;
procedure TForm1.Button1Click(Sender: TObject);
var
R: TRec;
i: integer;
begin
R.B:=1;
GetMem(R.Q, 10 * SizeOf(TElem)); // Выделили память под 10 элементов
try
for i := 0 to 9 do
with GetElem(R, i) do
begin
S1 := i;
S2 := i;
D1 := i;
end
finally
FreeMem(R.Q, 10 * SizeOf(TElem));
end
end;
← →
Прима (2009-09-18 14:36) [12]Спасибо.
← →
Anatoly Podgoretsky © (2009-09-18 15:03) [13]> Юрий Зотов (18.09.2009 14:07:11) [11]
Так у него проблема как раз с
TMArr = packed array [0..0] of TElem;
Массив размером на 1 элемент и проверка диапазонов ругается на это.
Эта техника из СИ и некоторое время успешнь использовалась в Паскале.
Правильнее указать диапазон с запасом, чем с недостатком.
← →
Прима (2009-09-21 15:09) [14]2 Юрий Зотов © (18.09.09 14:07) [11]
Я конечно извиняюсь, но пример не работает.
Вывожу так :
for I:=0 to 9 do
with R.Q[I] do
begin
Memo1.Lines.Add(Format("%d %d %d",[I,S1,S2]));
end;
← →
Palladin © (2009-09-21 16:12) [15]
> Прима (21.09.09 15:09) [14]
Так и кричит благим матом? "неработаю" мол...
← →
Юрий Зотов © (2009-09-21 16:40) [16]> Прима (21.09.09 15:09) [14]
А как Вы думаете, зачем понадобилась функция GetElem?
← →
Sapersky (2009-09-21 17:56) [17]ИМХО не нужна она там, разве что для контроля индексов. Проще прямо обращаться к элементам, иначе зачем вся эта возня с объявлением типов.
А если уж использовать функцию, то возвращать она должна указатель (PElem), или для модификации элементов должна быть отдельная функция SetElem.
← →
Sha © (2009-09-21 20:29) [18]> Anatoly Podgoretsky © (18.09.09 15:03) [13]
> Правильнее указать диапазон с запасом, чем с недостатком.
Это хоть обойти можно, а вот отрицательный индекс (константу) написать не дают.
← →
Юрий Зотов © (2009-09-21 20:48) [19]> Sapersky (21.09.09 17:56) [17]
1. Она нужна, чтобы обмануть "Range check error".
2. Что она должна возвращать - это дело вкуса.
3. Вот SetElem здесь как раз будет лишней.
← →
Прима (2009-09-21 21:53) [20]
> Так и кричит благим матом? "неработаю" мол...
Нет...она работает, но возвращаемые значения не те.
← →
Sapersky (2009-09-21 23:40) [21]Она нужна, чтобы обмануть "Range check error".
Чем обманывать, так проще вообще отключить (хотя бы локально, $R-). Быстрее работать будет.
Что она должна возвращать - это дело вкуса.
Вообще да, но в примере [11] - нет. Вы же там пытаетесь задать элементам значения через GetItem. Естественно, ничего не задаётся, поскольку всё пишется в возвращаемую переменную, а не в массив.
← →
Германн © (2009-09-22 02:05) [22]
> Прима (18.09.09 13:35) [8]
>
> Это понятно.
> Я хочу для себя разобраться как работать с [0..0]
А не надо с этим способом объявления "разбираться". Надо его не использовать никогда.
← →
Sapersky (2009-09-22 03:59) [23]Иногда бывает удобно, например, если некий API возвращает нетипизированный указатель, но мы точно знаем, что там массив - можно откастить к массиву и работать с относительным комфортом. Также можно "вырезать" фрагмент массива без копирования, просто сдвинув указатель.
Хотя я в большинстве случаев использую дин. массивы, в основном потому, что их содержимое можно посмотреть при отладке.
← →
Anatoly Podgoretsky © (2009-09-22 09:51) [24]> Sapersky (22.09.2009 03:59:23) [23]
Хорошо, но зачем для этого 0..0, а не 0..много
← →
Sapersky (2009-09-22 13:08) [25]Ну пусть будет 0..много, не принципиально. Хотя несколько громоздко получается, чтобы получить макс. размер приходится писать что-то вроде [0..(MaxInt div SizeOf(TElement))-1]. 0..MaxInt-1 компилятор не пропускает, слишком большой размер типа (кроме массива байтов, ест-но).
← →
Leonid Troyanovsky © (2009-09-22 13:26) [26]
> Sapersky (22.09.09 13:08) [25]
> писать что-то вроде [0..(MaxInt div SizeOf(TElement))-1].
const
MaxElem = MaxInt div SizeOf(TElem);
--
Regards, LVT.
← →
Anatoly Podgoretsky © (2009-09-22 13:38) [27]> Sapersky (22.09.2009 13:08:25) [25]
Ничего писать не надо, в системе уже объявлены нужные константы.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2009.11.08;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.006 c