Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.08.29;
Скачать: [xml.tar.bz2];

Вниз

Передать в функцию массив из структуры -- как???   Найти похожие ветки 

 
cvg   (2004-08-11 13:40) [0]

Hi Masters! Имеется структурка типа:

type MyRec =
record
 name:string;
 ar:array [0..5] of double;
......
end;
MyArr = array of MyRec;
var A:MyArr;

Как передать в функцию не один элемент -- скажем, A[n].name, -- а массив всех names?


 
Anatoly Podgoretsky ©   (2004-08-11 13:46) [1]

Функция не наблюдается
Но в принципе нужно создать тип массива.


 
wal ©   (2004-08-11 13:49) [2]

function aaa(arr: MyArr): ResultType;
Помоему так.

С уважением.


 
Anatoly Podgoretsky ©   (2004-08-11 13:51) [3]

Так как тип создан, то это правильно.


 
cvg   (2004-08-11 13:59) [4]

Ну-у, все-то целиком передать, конечно, можно, но только вот хотелось бы лишнее не пердавать. Скажем, если в функции используются только names, то, выходит, мне придется внутри функции помнить, что из переданной структуры надо отбрать именно все names. А если первый раз names, а второй names1 -- тогда как???


 
begin...end ©   (2004-08-11 14:16) [5]


> но только вот хотелось бы лишнее не пердавать

Можно передавать только ссылку.

> А если первый раз names, а второй names1 -- тогда как???

А что это за Names1? Ещё одно поле?
Так это уже должна быть другая функция. Или я чего-то не понял?


 
cvg   (2004-08-11 14:25) [6]

Ну, не пинай сильно -- я просто имел ввиду, что если у меня в структуре есть поля name и name1 и некоторая функция f() при первом вызове должна обработать все поля name, а при втором -- все поля name1, то как это ей красиво и корректно передать?


 
begin...end ©   (2004-08-11 14:31) [7]

Тогда, ИМХО, этой функции нужно передавать некий дополнительный параметр - какое поле обрабатывать.
Если функция должна обрабатывать name и names1 одинаковым образом, то можно, конечно, перед вызовом функции формировать соответствующий массив (из нужных полей) и уже его передавать в функцию.


 
Digitman ©   (2004-08-11 14:32) [8]


> хотелось бы лишнее не пердавать


передавай массив не по значению, а по ссылке


> при первом вызове должна обработать все поля name, а при
> втором -- все поля name1


организуй 2-й параметр в ф-ции, принимающей первым параметром массив по ссылке ... этот 2-й параметр будет указывать "номер вызова"


 
wal ©   (2004-08-11 14:32) [9]

function aaa(arr: MyArr, bbb:integer): ResultType;
begin
...
case bbb of
0: Do(arr[I].names);
1: Do(arr[I].names1)
2: и т.д.
...
end;

С уважением.


 
cvg   (2004-08-11 14:36) [10]

Типа, номер вызова передавать? Но это же страшно коряво! По идее функция вообще знать не должна, что ети массивы являются частью какой-то там структуры.


 
Digitman ©   (2004-08-11 14:36) [11]

function aaa(var arr: MyArr, bbb:integer): ResultType;
begin
...
case bbb of
0: for i := low(arr) to High(arr) do Processing(arr[i].names);
1: for i := low(arr) to High(arr) do Processing(arr[i].names1);

2: и т.д.
...
end;


 
cvg   (2004-08-11 14:40) [12]

To begin...end
ну, можноЮ конечно и так... Но мне-то бы хотелось что-нить типа

func(A.name); func(A.name1);


 
begin...end ©   (2004-08-11 14:42) [13]


> [10] cvg   (11.08.04 14:36)

Передавать НОМЕР ПАРАМЕТРА, ПОДЛЕЖАЩЕГО ОБРАБОТКЕ.
Или пусть у тебя будет не name и name1, а Name: array[0..1] of String, тогда передаёшь соответственно 0 или 1.

> [12] cvg   (11.08.04 14:40)


> func(A.name); func(A.name1);

Сделай функцию, в которую передаётся ТОЛЬКО ОДНА запись.
for I := Low to High do
 func(A[I].name);


?


 
cvg   (2004-08-11 14:45) [14]

To Digitman
Вот, уже теплее... Если бы только цикл for запихать в чего-нить типа функции и вызов ее делать не внутри функции ааа, а вне ее...


 
Digitman ©   (2004-08-11 14:48) [15]


> Если бы только цикл for запихать в чего-нить типа функции
> и


это что же, я еще и "запихивать" что-то куда-то за тебя должен ? совсем беда с головой у тебя приключилась ?


 
cvg   (2004-08-11 14:50) [16]

to begin...end
Ну это ж я для примера сказал, что name и name1. На самом-то деле их там до фига (штук 30) и с разными именами.


 
begin...end ©   (2004-08-11 14:56) [17]

type
 MyRec = record
   Names: array [0..29] of String;
   ...
 end;

 MyArr = array of MyRec;

var
 A: MyArr;

...

for I := Low(A) to High(A) do
 for J := 0 to 29 do
   Func(MyArr[I].Names[J]) // обработка одного поля одной записи


 
cvg   (2004-08-11 14:57) [18]

Коточе, если есть возможность соорудить что-нить типа

function f(word);
begin
for i := 0 to length(A) - 1 do
 <обработка полей A[i].&word>
end;

begin
f("name");

я был бы практически счастлив.


 
cvg   (2004-08-11 14:59) [19]

To begin...end
То есть, типа, переименовать их всех под одну гребенку?


 
begin...end ©   (2004-08-11 15:03) [20]


>  [19] cvg   (11.08.04 14:59)

Типа да.

Ну или см. [7], второй вариант. Но это будет хреново с точки зрения производительности. Да и коряво.


 
cvg   (2004-08-11 15:14) [21]

Проблема в том, что структурка у меня вышла такая:

type MyRec =
record
 name:string;
 ar:array [0..5] of double;
 avg0:array of double;
 avg7:array of double;
 avg8:array of double;
 ar1:array[0..4] of double;
 ar2:array[0..4] of double;
 arr:array [0..5] of double;
 buff:array [1..6] of double;
 es_war:integer;
 in_lot:integer;
 lots:integer;
 lpp:integer;
 MA_:double;
 MA_0:double;
 MA0:double;
 MA1:double;
 MA2:double;
 MA3:double;
 MA4:double;
 MA7:double;
 MA8:double;
 mass:array of double;
 mass1:array of double;
 mass2:array of double;
 max:double;
 max1:double;
 min:double;
 min1:double;
 op:integer;
 pair:integer;
 qu:double;
 start:double;
 switch:Boolean;
 zahl1:integer;
 zahl2:integer;
end;
MyArr = array of MyRec;

а существующие обращения к функциям такого типа:

A[n].arr[1] := combing(A[n].ar[1]/A[n].start*100,A[n].arr[1],1);
A[n].arr[2] := combing(A[n].ar[2]/A[n].start*100,A[n].arr[2],1);
A[n].buff[5] := A[n].arr[3]; A[n].buff[6] := A[n].arr[4];
A[n].arr[3] := combing(A[n].arr[1],A[n].arr[3],10);
A[n].arr[4] := combing(A[n].arr[2],A[n].arr[4],10);
putting(A[n].mass1,A[n].arr[3]); putting(A[n].mass2,A[n].arr[4]);
A[n].arr[5] := mixing(A[n].mass1,A[n].mass2,A[n].mass,index);
putting(A[n].mass,A[n].arr[5]);

где вместо A[n] должны иметься ввиду "все соответствующие поля из структуры A".


 
begin...end ©   (2004-08-11 15:17) [22]

Уф-ф...
И после этого ты будешь утверждать, что у тебя куча полей обрабатывается одной и той же функцией?


 
Digitman ©   (2004-08-11 15:18) [23]


> cvg   (11.08.04 15:14) [21]


у тебя полная каша в голове с понятиями "структура" и "массив"


> все соответствующие поля из структуры A


что за "структура A" ? нет в приведенном коде никаких "структур A" ! есть массив А !


 
KSergey ©   (2004-08-11 15:21) [24]

> [12] cvg   (11.08.04 14:40)
> ну, можноЮ конечно и так... Но мне-то бы хотелось что-нить
> типа
> func(A.name); func(A.name1);

Нельзя так.
По той простой причине, что A. не существует в принципе. Только A[x].


 
cvg   (2004-08-11 15:22) [25]

Ну, согласен, каша. Ты лучше как быть подскажи.


 
cvg   (2004-08-11 15:25) [26]

To KSergey
Это ж я идеальный вариант нарисовал. Мне бы что-нить, чтоб громоздкие циклы перед каждым обращениям к функциям не писать.


 
begin...end ©   (2004-08-11 15:27) [27]


> cvg

Желательно было с самого начала привести полное описание записи. Ну да ладно.
Теперь сформулируй задачу снова - какие поля из этой записи надо обрабатывать? И - одинаковым образом или нет?


 
KSergey ©   (2004-08-11 15:29) [28]

Лучше. На выбор.
а) создать несколько массивов вместо одной структуры (да, вроде как не красиво)
б) копировать перед вызовом в промежуточный массив.

Вообще, есть еще 3-й, но будет ли он лучше и понятнее, особенно в разрезе паскаля? ;) Хотя в Си я бы так и сделал ;)
Смысл в передаче указателя на массив структур и относительного смещения в структуре требуемой строки.
Но тут тоже голову поломать немного надо, да и над вопросом - будет ли это эффективнее, т.е. возможно каздый раз при обработке будет генерится (может и не явно компилятором) временная строка, тогда решение с временным массивом будет хотя бы понятнее. Ну либо надо хорошо знать тонкости как компилируются конкретны выражения со строками в дельфи. Увы, я в деталях не знаю.


 
Digitman ©   (2004-08-11 15:30) [29]


> cvg   (11.08.04 15:22) [25]


ты для начала сформулируй задачу максимально точно и терминологически корректно - будет и подсказка.. хотя, думаю, она тебе и не понадобится, если ты это сделаешь) ... решение придет само собой, в ходе формулировки)


 
KSergey ©   (2004-08-11 15:33) [30]

> [28] KSergey ©   (11.08.04 15:29)

Дополнение.
Если бы строки были фиксированной длины - то по 3-му варианту вполне можно идти.
Ну т.е. для обработки не динамических строк, а статических по размеру элеменетов - вообще милое дело (в том числе числа).


 
cvg   (2004-08-11 15:40) [31]

А как-нить по номеру поля в структуре обращаться к этому полю можно?


 
begin...end ©   (2004-08-11 15:42) [32]


> [31] cvg   (11.08.04 15:40)
> А как-нить по номеру поля в структуре обращаться к этому полю можно?

Ну только смещение вычислять, как KSergey предложил. ИМХО.


 
KSergey ©   (2004-08-11 15:49) [33]

> [31] cvg   (11.08.04 15:40)
> А как-нить по номеру поля в структуре обращаться к этому
> полю можно?

Нет, ибо нет у поля номера
Впрочем, тут есть еще такой вариант.
Вместо всех String полей сделать массив (границы в примере - условны)

type MyRec =
record
 arrStr[1..5]: String
....
end;

В arrStr под разными индексами хранить определенные по смыслу значения.
А если еще вместо [1..5] определить перечислимый тип с осмысленными названиями - то и вообще вполне читабельный код получится, надо дтметить..
Тогда просто передавать ссылку на массив структур и индекс в arrStr, предназначенный к обработке.
А что, вполне паскалевое решение.
А то я все по нездоровой привычке чуть что - так сразу указатели ;)


 
cvg   (2004-08-11 15:49) [34]

Так это если поля одного типа. А если разных -- то у каждого свою длину учитывать? А если типа string или массив?


 
KSergey ©   (2004-08-11 15:51) [35]

> [34] cvg   (11.08.04 15:49)

Я что-то не пойму: как вы собираетесь одним и тем же кодом обрабатывать Integer, String, DateTime и т.д.???!! Или я вообще нифига не понял?


 
begin...end ©   (2004-08-11 15:52) [36]


> [35] KSergey ©   (11.08.04 15:51)

Я это с поста [5] пытаюсь понять, обрати внимание :-)


 
Digitman ©   (2004-08-11 15:58) [37]


> cvg   (11.08.04 15:49) [34]


при таких требованиях ты подходишь к концепции и реализации не с той стороны

смотри, к примеру, как реализовано св-во Fields[] класса TDataset и делай как минимум по образу и подобию


 
Erik1   (2004-08-11 16:01) [38]

To cvg
Каша у тебя в голове. Сделай проще создай клас, в классе опиши нужные тебе структуры. Причем делай Array of record а не наоборот. После переворота тебе легче станет, а область видемости будет ограничена классом. Действйу по правилу если значения ненужны для совместного вычисления дели на разные структуры или даже классы.


 
cvg   (2004-08-11 16:11) [39]

Просто сначала это были отдельные переменные и массивы, потом оказалось, что их надо дублировать для нескольких случаев, причем вычислять все параллельно. Вот. TDataSet погляжу.


 
KSergey ©   (2004-08-11 16:15) [40]

Параллельно - это прикольно.
Но вы можете ответить на [35] KSergey ©   (11.08.04 15:51)?? Просто из любопытства? Приведите небольшой пример кода обработки...


 
Digitman ©   (2004-08-11 16:17) [41]


> причем вычислять все параллельно


да уж .. из другой оперы это ария


 
cvg   (2004-08-11 16:33) [42]

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

for i:=low(a) to high(a)
func(a[i].abc);

а что-нить типа

func(abc);

А пример кода я уже приводил. Ну, вот еще:

A[n].MA0 := pushing(A[n].avg0,A[n].ar[3]/A[n].start*100);
A[n].MA3 := A[n].arr[3] - A[n].MA1;
A[n].MA4 := A[n].arr[4] - A[n].MA2;

A[n].MA7 := pushing(A[1].avg7,A[n].ar[3]/A[n].start*100);
A[n].MA8 := pushing(A[1].avg8,A[n].qu);

A[n].arr[1] := combing(A[n].ar[1]/A[n].start*100,A[n].arr[1],1);
A[n].arr[2] := combing(A[n].ar[2]/A[n].start*100,A[n].arr[2],1);
A[n].buff[5] := A[n].arr[3]; A[n].buff[6] := A[n].arr[4];
A[n].arr[3] := combing(A[n].arr[1],A[n].arr[3],10);
A[n].arr[4] := combing(A[n].arr[2],A[n].arr[4],10);
putting(A[n].mass1,A[n].arr[3]); putting(A[n].mass2,A[n].arr[4]);
A[n].arr[5] := mixing(A[n].mass1,A[n].mass2,A[n].mass,index);
putting(A[n].mass,A[n].arr[5]);

if A[n].MA1 = 0 then A[n].MA1 := A[n].ar[1]/A[n].start*100;
if A[n].MA1 - A[n].ar[1]/A[n].start*100 >= 0.005
then A[n].MA1 := A[n].ar[1]/A[n].start*100
else A[n].MA1 := max(A[n].MA1,A[n].ar[1]/A[n].start*100);
if A[n].MA2 = 0 then A[n].MA2 := A[n].ar[2]/A[n].start*100;
if A[n].ar[2]/A[n].start*100 - A[n].MA2 >= 0.005
then A[n].MA2 := A[n].ar[2]/A[n].start*100
else A[n].MA2 := min(A[n].MA2,A[n].ar[2]/A[n].start*100);


 
Erik1   (2004-08-11 16:41) [43]

Если переменые дублируются, то должны быть представлены тойже структорой. Тоесть:
Type
 MyType := Array of MyRecord;
A: MyType;
B: MyType;
...
Копирование:
B := Copy(A);
Тоесть сначала надо вычислить один случай, все скопировать и только после этого идем дальше. Иначе получается то, что имеем. И еще мне кажется вычисления сильно перерисать надо. Тоесть начать с изменения алгоритма.


 
KSergey ©   (2004-08-11 16:42) [44]

> [42] cvg   (11.08.04 16:33)

По поводу [33] KSergey ©   (11.08.04 15:49) что-то сказать можем?

Во только по поводу приведенного куска - я никак не пойму как он состыкуется с func(abc);
В каждой строчке - работаем с разными полями структуры. Это все внутри одного цикла или как? Нормально можно задачу объяснять??


 
cvg   (2004-08-11 16:52) [45]

Согласен, что вычисления придется переписывать там, где идет проверка условий.

Задача в грубом виде такая:
1-й вариант (был): на основе ряда некоторых динамично изменяющихся данных принимать некоторые решения;
2-й вариант (сейчас): делать то же самое на основании нескольких рядов данных.


 
KSergey ©   (2004-08-11 16:54) [46]

Доктор, меня игнорируют! ;)
Все, я потерял интерес, т.к. ничего уже не понимаю.



Страницы: 1 2 вся ветка

Форум: "Основная";
Текущий архив: 2004.08.29;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.57 MB
Время: 0.031 c
1-1092663189
Hermes
2004-08-16 17:33
2004.08.29
Как убрать символы #13#10


8-1086673664
X-Disa
2004-06-08 09:47
2004.08.29
Смена иконки


4-1090242754
Death_R
2004-07-19 17:12
2004.08.29
Отключение функциональных клавиш


3-1091864650
serg128
2004-08-07 11:44
2004.08.29
Как сортировать по вычислимому полю?


1-1092137241
Pavelkq
2004-08-10 15:27
2004.08.29
Сравнение двух TStringList-ов





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский