Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.08.29;
Скачать: CL | DM;

Вниз

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

 
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)?? Просто из любопытства? Приведите небольшой пример кода обработки...



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

Текущий архив: 2004.08.29;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.027 c
1-1092306192
Lera
2004-08-12 14:23
2004.08.29
Формы.


1-1092385796
starik30
2004-08-13 12:29
2004.08.29
Многопоточность + FIBPlus


3-1091775556
ydv
2004-08-06 10:59
2004.08.29
Объединение таблиц


3-1091623108
Shama_n
2004-08-04 16:38
2004.08.29
Как получить кол-во записей удовлетворяющих условию


1-1092073269
KOMbI4
2004-08-09 21:41
2004.08.29
Встроенный Ассемблер