Форум: "Основная";
Текущий архив: 2006.03.19;
Скачать: [xml.tar.bz2];
Вниз$R- в созданном юните, непашет на уровне компиляции Найти похожие ветки
← →
imm (2006-02-09 23:22) [0]Создаю новый юнит, пихаю туда
{$R-} //Убираем проверку индекса
type
TDArray = array[0..0] of Integer;
PDArray = ^TDArray;
implementation
procedure Hello;
var
t: PDArray;
begin
...
//Выделяем память
GetMem(t, SizeOf(Integer)*10);
//А здесь ошибка на этапе компиляции
t^[5] := 10;
...
end;
Как это исправить, то есть как это откомпилировать???? Помогите пожалуйста. За раннее вам благодарен.
← →
Джо © (2006-02-09 23:30) [1]А почему бы не усложнять себе жизнь и не воспользоваться динамическим массивом array of Integer?
← →
Джо © (2006-02-09 23:33) [2]В принципе, над t, как и над любым указателем, можно выполнять операции увеличения/уменьшения, т.е, например Inc(t,SizeOf(Integer)*2) - сместит указатель на второй элемент.
← →
Imm (2006-02-09 23:47) [3]Я тут подумал взвесил все за и против и решил, что действительно открытим массивом воспользоваться будет удобнее, но всё же как откомпилировать приведённый мной код, сейчас это мне походу не понадобится, но на будущее будет полезно. Я был бы очень благодарен за ответ.
← →
Джо © (2006-02-10 00:00) [4]> [3] Imm (09.02.06 23:47)
> Я тут подумал взвесил все за и против и решил, что действительно
> открытим массивом воспользоваться будет удобнее, но всё
> же как откомпилировать приведённый мной код, сейчас это
> мне походу не понадобится, но на будущее будет полезно.
> Я был бы очень благодарен за ответ.
Такоеt^[5] := 10
не откомпилируешь ни с какой директивой.
А можно, как я уже и говорил, сделать так:Inc (t,6*SizeOf(Integer));
t^[0] := ...
← →
Джо © (2006-02-10 00:07) [5]Только первоначальный указатель не забыть сохранить, для FreeMem.
← →
palva © (2006-02-10 00:13) [6]{$R-} отвечает за проверку диапазона на этапе выполнения. А на этапе компиляции, судя по всему всегда производится проверка константных выражений на соответствие диапазону. Как это отключить - не понятно. Но для неконстантных выражений компилироваться будет. Например:
i := 5;
t^[i] := 10;
← →
Джо © (2006-02-10 00:17) [7]Да, действительно, слушайте [6] palva, я сегодня заработался, видимо, вот и усложняю :). Так действительно будет проще всего, кажется.
← →
Германн © (2006-02-10 02:27) [8]2 imm (09.02.06 23:22)
Может лучше было бы объяснить задачу?
Я, например, никак не могу понять сабж:type
TDArray = array[0..0] of Integer;
PDArray = ^TDArray;
implementation
procedure Hello;
var
t: PDArray;
begin
...
//Выделяем память
GetMem(t, SizeOf(Integer)*10);
//А здесь ошибка на этапе компиляции
t^[5] := 10;
...
end;
← →
Leonid Troyanovsky © (2006-02-10 08:34) [9]
> Imm (09.02.06 23:47) [3]
> Я тут подумал взвесил все за и против и решил, что действительно
> открытим массивом воспользоваться будет удобнее, но всё
> же как откомпилировать приведённый мной код, сейчас это
> мне походу не понадобится, но на будущее будет полезно.
> Я был бы очень благодарен за ответ.
const
MaxArraySize = ..;
type
TDArray = array[0..MaxArraySize-1] of Integer;
PDArray = ^TDArray;
--
Regards, LVT.
← →
palva © (2006-02-10 10:04) [10]> Может лучше было бы объяснить задачу?
Это был стандартный метод моделирования динамических массивов, когда динамических массивов в Delphi не было.
← →
han_malign © (2006-02-10 15:17) [11]
> const
> MaxArraySize = ..;
>
> type
> TDArray = array[0..MaxArraySize-1] of Integer;
> PDArray = ^TDArray;
>
PIntegerArray - не судьба?
← →
han_malign © (2006-02-10 15:22) [12]
> //А здесь ошибка на этапе компиляции
> t^[5] := 10;
- а вот здесь, что самое интересное, ее не будет:for i:= 5 to 5 do t^[i] := 10;
По моему, для массива с неизвестной начальной длинной, обращение по вычисляемому ииндексу более логично... Не так ли?
← →
han_malign © (2006-02-10 15:23) [13]palva © (10.02.06 00:13) [6]
- упс, не заметил...
← →
Leonid Troyanovsky © (2006-02-10 16:41) [14]
> han_malign © (10.02.06 15:17) [11]
> > TDArray = array[0..MaxArraySize-1] of Integer;
> PIntegerArray - не судьба?
Может быть в нем и есть сермяжная правда.
Но, лучше б было предложить оное непосредственно вопрошаещему.
Т.е., про то "как" я, IMHO, ответил прямо, без ссылок.
--
Regards, LVT.
← →
PVOzerski © (2006-02-10 17:03) [15]В общем, я в подобных случаях иногда просто объявляю типизированную костанту
const five: integer = 5;
и потом использую как индекс массива. А вообще-то, что заставляет ограничивать верхнюю границу массива нулем при описании, в общем-то, фиктивного типа TDArray?
← →
Alex Konshin © (2006-02-11 08:18) [16]PVOzerski © (10.02.06 17:03) [15]
А вот это кстати иногда требуется в record и очень раздражает, что в Delphi нельзя описать массив нулевой длины. Кстати, замечу, что у автора массив единичной длины.
А пример, где это нужно:TMyPackage = record
Length : Integer;
Flags : TMyPackageFlags;
Data : Array [0:-1] of Byte; // вот так, к сожалению, нельзя
end;
const PackageHeaderSize = SizeOf(TMyPackage);
← →
TUser © (2006-02-11 10:45) [17]> Data : Array [0:-1] of Byte; // вот так, к сожалению, нельзя
А зачем?
← →
Германн © (2006-02-12 03:54) [18]Кстати, Alex, а действительно зачем?
Чем тебе противен Pointer?
← →
atruhin © (2006-02-12 08:02) [19]>>А зачем?
Тоже приходилось пользоваться. Для byte вроде незачем проще PChar, а вот если Data - record, да даже Integer удобнее не нужно каждый раз приводить тип.
например integer(Data[NumElem*SizeOf(Integer)]).
Я делал так.
TData = array [0..1000] of record ..... end;
PData = ^TData;
var
MyPackage : TMyPackage; // без Data
Data : PData;
begin
.....
Data := inc(MyPackage, SizeOf(MyPackage));
..Data^..
← →
jack128 © (2006-02-12 23:30) [20]Германн © (12.02.06 3:54) [18]
Чем тебе противен Pointer?
Тем, что занимает лишние 4 байта. Тем что сохранить такую запись простым Stream.WriteBuffer(MyPackegeVar, MyPackegeVar.Length); невозможно будет. Наверное поэтому..
← →
Alex Konshin © (2006-02-13 08:16) [21]TUser © (11.02.06 10:45) [17]
> Data : Array [0:-1] of Byte; // вот так, к сожалению, нельзя
А зачем?
Затем, что перевести на Pascal конструкцию из C/C++ [0] нельзя. А надо.
Например:
typedef struct _DISK_INFORMATION {
UCHAR Length[2];
UCHAR DiskStatus : 2;
UCHAR LastSessionStatus : 2;
UCHAR Erasable : 1;
UCHAR Reserved1 : 3;
UCHAR FirstTrackNumber;
UCHAR NumberOfSessions;
UCHAR LastSessionFirstTrack;
UCHAR LastSessionLastTrack;
UCHAR Reserved2 : 5;
UCHAR GEN : 1;
UCHAR DBC_V : 1;
UCHAR DID_V : 1;
UCHAR DiskType;
UCHAR Reserved3[3];
UCHAR DiskIdentification[4];
UCHAR LastSessionLeadIn[4]; // MSF
UCHAR LastPossibleStartTime[4]; // MSF
UCHAR DiskBarCode[8];
UCHAR Reserved4;
UCHAR NumberOPCEntries;
OPC_TABLE_ENTRY OPCTable[0];
} DISK_INFORMATION, *PDISK_INFORMATION;
И в VCL есть места, где массивы нулевой длины не помешали бы:
PPTypeInfo = ^PTypeInfo;
PTypeInfo = ^TTypeInfo;
TTypeInfo = record
Kind: TTypeKind;
Name: ShortString;
{TypeData: TTypeData}
end;
TPropData = packed record
PropCount: Word;
PropList: record end;
{PropList: array[1..PropCount] of TPropInfo}
end;
← →
Alex Konshin © (2006-02-13 08:20) [22]Оттуда же еще пример:
PTypeData = ^TTypeData;
TTypeData = packed record
case TTypeKind of
tkUnknown, tkLString, tkWString, tkVariant: ();
tkInteger, tkChar, tkEnumeration, tkSet, tkWChar: (
OrdType: TOrdType;
case TTypeKind of
tkInteger, tkChar, tkEnumeration, tkWChar: (
MinValue: Longint;
MaxValue: Longint;
case TTypeKind of
tkInteger, tkChar, tkWChar: ();
tkEnumeration: (
BaseType: PPTypeInfo;
NameList: ShortStringBase;
EnumUnitName: ShortStringBase));
tkSet: (
CompType: PPTypeInfo));
tkFloat: (
FloatType: TFloatType);
tkString: (
MaxLength: Byte);
tkClass: (
ClassType: TClass;
ParentInfo: PPTypeInfo;
PropCount: SmallInt;
UnitName: ShortStringBase;
{PropData: TPropData});
tkMethod: (
MethodKind: TMethodKind;
ParamCount: Byte;
ParamList: array[0..1023] of Char
{ParamList: array[1..ParamCount] of
record
Flags: TParamFlags;
ParamName: ShortString;
TypeName: ShortString;
end;
ResultType: ShortString});
tkInterface: (
IntfParent : PPTypeInfo; { ancestor }
IntfFlags : TIntfFlagsBase;
Guid : TGUID;
IntfUnit : ShortStringBase;
{PropData: TPropData});
tkInt64: (
MinInt64Value, MaxInt64Value: Int64);
tkDynArray: (
elSize: Longint;
elType: PPTypeInfo; // nil if type does not require cleanup
varType: Integer; // Ole Automation varType equivalent
elType2: PPTypeInfo; // independent of cleanup
DynUnitName: ShortStringBase);
end;
← →
han_malign © (2006-02-13 10:37) [23]
> что в Delphi нельзя описать массив нулевой длины
- ну, допустим, в С++ это, нынче, тоже нерекомендумемая конструкция - warning выдает...
И приходится делать явно:PData pData = (PData)(pRecord +1);
а смещение следующей записи, по любому, исподподвыподверта надо вычислятьpRecordNext = (PRecord)((PBYTE)pRecord + pRecord.cbSize);
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2006.03.19;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.014 c