Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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.007 c
15-1252520131
мдфв
2009-09-09 22:15
2009.11.08
не программу, надо на бумаге, тупо по Герону- похоже не тот пут


2-1253215998
Артем
2009-09-17 23:33
2009.11.08
tabsheet


4-1221305909
Aggressor
2008-09-13 15:38
2009.11.08
Start->Run vs Start->cmd


15-1252787409
Юрий
2009-09-13 00:30
2009.11.08
С днем рождения ! 13 сентября 2009 воскресенье


15-1245951607
Petr V. Abramov
2009-06-25 21:40
2009.11.08
работа кипит :)





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский