![]() |
|
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]()
|
|
| Scrip |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 34 Регистрация: 8.5.2004 Репутация: нет Всего: нет |
Можно ли считать открытый массив динамическим массивом предствляющим собой параметр подпрограммы?
__________________________________________________________ Что такое конструктор массива и для чего он нужен? Это сообщение отредактировал(а) Scrip - 24.5.2004, 14:42 |
|||
|
||||
| Kesh |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2488 Регистрация: 31.7.2002 Где: Германия, Saarbrü cken Репутация: 4 Всего: 54 |
Мне вопрос непонятен, поясни, что такое открытый массив?..
Добавлено @ 17:35 Что ты имеешь в виду под конструктором массива? SetLength? -------------------- ![]() |
|||
|
||||
| Jey_k |
|
|||
![]() WEB-командир ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 4149 Регистрация: 16.11.2003 Где: Москва Репутация: 1 Всего: 61 |
Scrip
массивы можно, конечно, передавать как параметры подпрограммы, а что такое открытый массив? Уж не объявленный ли глобально? А динамический массив, насколько мне известно, тот у которого размерность может менятся в нужных случаях. Если все так, то связи в первом предложении не вижу(не обижайся, может не так понял) А конструктор-процедура создания. qwe:array[1..10] of integer; например |
|||
|
||||
| p0s0l |
|
||||
![]() Г-н Посол ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 3668 Регистрация: 13.7.2003 Где: 58°38' с.ш. 4 9°41' в.д. Репутация: 58 Всего: 112 |
Открытый массив - массив неизвестного размера. Пример:
Но это не динамический массив. Ответ на вопрос - нет. К примеру, я не смогу в Proc1 написать SetLength(m, 10); Сколько выделил памяти под m, столько и могу использовать... Можно передать дин. массив в качестве открытого массива, также как и статический:
При передаче дин. массива передается указатель на первый элемент данных, и длина дин. массива (которая не известна на этапе компиляции). При передаче стат. массива в качестве открытого массива длина массива сразу известна на этапе компиляции... -------------------- С уважением, г-н Посол. |
||||
|
|||||
| p0s0l |
|
|||
![]() Г-н Посол ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 3668 Регистрация: 13.7.2003 Где: 58°38' с.ш. 4 9°41' в.д. Репутация: 58 Всего: 112 |
ЗЫ: Насчет статических массивов: можно схитрить насчет длины. Например, для приведенной выше процедуры можно сделать так:
В результате, хоть и размер статического массива = 8, обработке в Proc1 пойдут только первый 6 (5+1=6) элементов... Ну это так, мало ли кому будет лень передавать еще один параметр для указания размера массива... -------------------- С уважением, г-н Посол. |
|||
|
||||
| p0s0l |
|
||||||||
![]() Г-н Посол ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 3668 Регистрация: 13.7.2003 Где: 58°38' с.ш. 4 9°41' в.д. Репутация: 58 Всего: 112 |
Пример:
Тут m - открытый массив. Пример вызова:
Пример использования конструктора:
Думаю, из примера видно что конструктор налету собирает массив. -------------------- С уважением, г-н Посол. |
||||||||
|
|||||||||
| Unregistered |
|
||||||
|
Unregistered |
p0s0l, чего-то не понял.... в приведенном тобой коде, в процедуру передается динамический массив без параметра его длины... А дальше ты пишешь, что надо передавать длину массива. И так ли обязательно передавать длину массива? У меня написана длл в которой реализованы такие функции:
Вызывая первую функцию я передаю ей динамический массив, в CheckCS передаю и динамический массив и открытый массив - SizeOf отлично справляется (как видно нет параметра передающего длину массива). Твой ответ заставил меня задуматься, а правильно ли я это реализовал? Поясни, пожалуйста. PS написано несколько программ с использованием этой длл, и все нормально работает. |
||||||
|
|||||||
| p0s0l |
|
|||
![]() Г-н Посол ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 3668 Регистрация: 13.7.2003 Где: 58°38' с.ш. 4 9°41' в.д. Репутация: 58 Всего: 112 |
Я неправильно выразился. И имел в виду, что длина массива передается неявным параметром, что я потом и показал с помощью "псевдо"-функции...
-------------------- С уважением, г-н Посол. |
|||
|
||||
| Scrip |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 34 Регистрация: 8.5.2004 Репутация: нет Всего: нет |
Непонятно. Что значит конструктор налету собирает массив? Какой массив? Ведь при выполнении процедуры Proc1 не описано каким фактическим параметром заменить формальный параметр m. Это сообщение отредактировал(а) Scrip - 25.5.2004, 13:44 |
||||
|
|||||
| Unregistered |
|
|||
|
Unregistered |
p0s0l, спасибо. С асмом у меня туговато.
|
|||
|
||||
| p0s0l |
|
||||||
![]() Г-н Посол ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 3668 Регистрация: 13.7.2003 Где: 58°38' с.ш. 4 9°41' в.д. Репутация: 58 Всего: 112 |
Какой массив ? Вот такой: [1,6,4,7,3,4,a,b,c,d] - в квадратных скобках друг за другом перечислены элементы передаваемого массива... Что значит "Налету собирает" ? Конструктор создает в стеке временный массив из перечисленных элементов, и передает указатель на него и длину (но это мы не видим), после завершения вызванной процедуры массива уже не будет... Конструктором можно пользоваться только для передачи параметров. И они не могут передаваться в качестве var-параметров (понятно почему)... Вот два абсолютно эквивалентных примера (даже код в результате генерится одинаковый):
-------------------- С уважением, г-н Посол. |
||||||
|
|||||||
| Scrip |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 34 Регистрация: 8.5.2004 Репутация: нет Всего: нет |
Если "Открытый массив - массив неизвестного размера", то под m память вообще не выделена. Так? Или ... нет... не так Добавлено @ 14:23 Все, с конструктором разобрался! Это сообщение отредактировал(а) Scrip - 25.5.2004, 14:23 |
|||
|
||||
| p0s0l |
|
|||
![]() Г-н Посол ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 3668 Регистрация: 13.7.2003 Где: 58°38' с.ш. 4 9°41' в.д. Репутация: 58 Всего: 112 |
Выделена. Процедура Proc1 на этапе компиляции не знает размер массива. При выполнении же программы она в качестве дополнительного параметра (которого мы не видим) получает размер массива... -------------------- С уважением, г-н Посол. |
|||
|
||||
| Kesh |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2488 Регистрация: 31.7.2002 Где: Германия, Saarbrü cken Репутация: 4 Всего: 54 |
Разве?.. Мне казалось, что получив указатель (только его)... Она уже сама определяет размер массива... Я не отрицаю того, что этот размер хранится в программе, но по-моему в процедуру он в заголовке не передается... -------------------- ![]() |
|||
|
||||
| p0s0l |
|
|||
![]() Г-н Посол ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 3668 Регистрация: 13.7.2003 Где: 58°38' с.ш. 4 9°41' в.д. Репутация: 58 Всего: 112 |
Kesh, если я тебе дам только указатель на ячейку памяти, как ты узнаешь сколько массив занимает ? Он может и 10 байт занимать, а может 10 мб...
Если я в var'е написал: m : array [0..31] of byte; То m займет ровно 32 байта. В памяти нигде не хранится размер этого массива... -------------------- С уважением, г-н Посол. |
|||
|
||||
| Scrip |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 34 Регистрация: 8.5.2004 Репутация: нет Всего: нет |
p0s0l, а сколько выделена? Намерняка мы этого опять незнаем
Размер массива процедуры Proc1 равен фактичекому параметру, заменившему формальный параметр процедуры proc1. Если понял что я сказал ответь пожалста. |
|||
|
||||
| p0s0l |
|
|||
![]() Г-н Посол ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 3668 Регистрация: 13.7.2003 Где: 58°38' с.ш. 4 9°41' в.д. Репутация: 58 Всего: 112 |
Ну вроди типа того...
-------------------- С уважением, г-н Посол. |
|||
|
||||
| Kesh |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2488 Регистрация: 31.7.2002 Где: Германия, Saarbrü cken Репутация: 4 Всего: 54 |
p0s0l Ну дал ты мне указатель m: array of integer; Ну и что мне мешает сделать так
-------------------- ![]() |
|||
|
||||
| p0s0l |
|
|||
![]() Г-н Посол ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 3668 Регистрация: 13.7.2003 Где: 58°38' с.ш. 4 9°41' в.д. Репутация: 58 Всего: 112 |
Kesh, ну и как же по-твоему прога узнает значение High(m) ?
Из космоса бог пошлет что ли ? Как раз этот самый High(m) и передается в качестве неявного невидимого параметра... -------------------- С уважением, г-н Посол. |
|||
|
||||
| Kesh |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2488 Регистрация: 31.7.2002 Где: Германия, Saarbrü cken Репутация: 4 Всего: 54 |
А ты уверен, что он передается, а не хранится в программе?..
-------------------- ![]() |
|||
|
||||
| p0s0l |
|
|||
![]() Г-н Посол ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 3668 Регистрация: 13.7.2003 Где: 58°38' с.ш. 4 9°41' в.д. Репутация: 58 Всего: 112 |
Kesh, такое ощущение, что ты надо мной издеваешься...
В самом начале было сказано, что у открытого массива длина на этапе компиляции неизвестна. Как тогда High(m) может быть известен компилятору, если процедуре могут передать как массив из 10 элементов, так и массив из 1000 элементов ? Где этот High(m) по-твоему может хранится ? Это раз. Во-вторых, тоже, почти в начале же выявил с помощью псевдо-функции неявный параметр, который как раз является High(m)... -------------------- С уважением, г-н Посол. |
|||
|
||||
| Kesh |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2488 Регистрация: 31.7.2002 Где: Германия, Saarbrü cken Репутация: 4 Всего: 54 |
p0s0l Ничего я над тобой не издеваюсь... Мне в самом деле непонятно...
P.S. Мне действительно интересно... -------------------- ![]() |
||||||
|
|||||||
| p0s0l |
|
||||||||||
![]() Г-н Посол ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 3668 Регистрация: 13.7.2003 Где: 58°38' с.ш. 4 9°41' в.д. Репутация: 58 Всего: 112 |
Гм... Пример:
Два массива разной длины начинаются с одного и того же адреса (накладываются друг на друга). В обоих вызовах Proc1 мы передаём указатель на одну и ту же ячейку памяти... И как процедура Proc1 определит, длину какого массива ей использовать: a и b ? Ведь по твоей гипотезе ей передается только указатель... Так что тут облом будет...
Ну если не веришь - проверь сам. Набери чуть выше приведенный пример. В дебаггере глянь на вызовы Proc1:
lea eax, [ebp-$28] в обоих вызовах загружает в eax один и тот же адрес - начало массива a (или массива b, т.к. они наложены друг на друга). Далее в edx засовывается макс. элемент массива (тот самый High(m)). Далее идет вызов Proc1... -------------------- С уважением, г-н Посол. |
||||||||||
|
|||||||||||
| Kesh |
|
||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2488 Регистрация: 31.7.2002 Где: Германия, Saarbrü cken Репутация: 4 Всего: 54 |
И что по-твоему означает call @DynArrayHigh Добавлено @ 23:36 Оно же засовывает High(m) в edx... a в Proc1 передается eax... Мне вот интересно... Ведь Proc1 берет значение из edx сама... Этот самый High берется из программы... -------------------- ![]() |
||||||||
|
|||||||||
| Girder |
|
|||
![]() Лентяй 2 ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1993 Регистрация: 12.5.2004 Репутация: 31 Всего: 155 |
Как не напиши:
procedure Proc1(var m : array of integer); или procedure Proc1(m : array of integer); в Proc1 - передается указатель на массив и не явно максимальный номер массима. Если напишим: var XXX: array [1..2] of .. begin ... Proc1(xxx); ... end; то в Proc1 - длина массива без проблемм опредилится. А если напишим: Type TXXXP:array of ... var XXX: array of .. XXXP:^TXXXP; n:array of .. T:TList; begin SetLength(XXX,...) ... Proc1(xxx); ... n:=xxx; SetLength(n,...) ... Proc1(n); ... T:=TList.Create; New(XXXP); XXXP^:=n; T.ADD(XXXP); ... XXX:=T.Items[...]; ... Proc1(xxx); ... end; то в Proc1 - при определении длины массива случаются осечки. По этому лудше всегда дополнительно указывать явно максимальное значение массива, т.е: procedure Proc1(var m : array of integer;IMax:integer); -------------------- Как слышим, так и пишим. Истина где-то там... |
|||
|
||||
| p0s0l |
|
||||||||||
![]() Г-н Посол ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 3668 Регистрация: 13.7.2003 Где: 58°38' с.ш. 4 9°41' в.д. Репутация: 58 Всего: 112 |
Kesh, ты хоть представляешь о чем речь идёт ? Я тебе об одном, а ты оказывается совсем о другом...
Я сказал, что при передаче массива в качестве отрытого массива процедуре Proc1 передаётся: 1) Адрес начала данных 2) № макс. элемента массива (High(m)) (неявно) И далее дискуссия шла именно об этом. Я тебе привел пример со статическим массивом. А ты - с динамическим:
Как видишь, DynArrayHigh вызывается перед вызовом Proc1, а не в самой Proc1. Далее идёт:
А edx КУДА передаётся ??? Он идёт туда же в Proc1, и если в процедуре Proc1 встретится High(m), то будет использоваться значение edx. Как ни крути, но ты сам щас доказал, что передается адрес массива (eax) и длина массива (edx)... Я так понял, ты пытаешься доказать, что длина динамического массива хранится где-то в ОП. Зачем мне это доказывать ? Я и так с тобой бы согласился... Но длина статического массива всё же нигде не хранится... Girder, если вместо
то всё ок будет, т.к. ты пытался сделать что-то не очень понятное (указатель присвоить массиву, в итоге компилятор решил вообще ничего не делать с xxx). Или же так:
-------------------- С уважением, г-н Посол. |
||||||||||
|
|||||||||||
| Girder |
|
|||
![]() Лентяй 2 ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1993 Регистрация: 12.5.2004 Репутация: 31 Всего: 155 |
Это и имелось в виду! Просто ошибся. И я не спорю с тобой, а стараюсь разъяснить. Когда то я тоже писал вот-так: -procedure Proc1(var m : array of ...); или(кто как хочет пускай и пишит) -procedure Proc1(m : array of ...); Но в один прекрасный момент сталкнулся с проблеммой не правильного определения размера массива в Не спорю - это могло произойти только на моем компьютере, в данном версии компилятора, в это утро, при этом расположении планет и т.п. хрень - но это произошло(а за много лет программирования в Delphi не первый раз сталкнулся с этой проблеммой) Это сообщение отредактировал(а) Girder - 28.5.2004, 03:11 -------------------- Как слышим, так и пишим. Истина где-то там... |
|||
|
||||
| p0s0l |
|
||||
![]() Г-н Посол ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 3668 Регистрация: 13.7.2003 Где: 58°38' с.ш. 4 9°41' в.д. Репутация: 58 Всего: 112 |
Странно это. Тем более что было сказано, что не в вызываемой процедуре определяется размер массива, а в вызывающей... Всё равно, интересно было бы взгянуть на это, но это, как понимаю, единственный случай, и его теперь не воссоздать. Но суть не в этом. Эта проблема не открытого массива, а твоя проблема. Или проблема TList'а, или чего там использовал. Ведь в твоем примере, если сделать так:
И тут бы всплыла точно та же проблема у тебя. Без всяких передач массива в другую процедуру. Потому что ошибка определения длины происходит тут, а не там (в вызываемой процедуре). (В данном случае вообще ошибки не происходит, просто делается не то что хотелось...) -------------------- С уважением, г-н Посол. |
||||
|
|||||
| Girder |
|
||||||
![]() Лентяй 2 ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1993 Регистрация: 12.5.2004 Репутация: 31 Всего: 155 |
О... с этим я сталкнулся еще раньше.
Ни чё, зато заставляет быть более предусмотрительным при написании программы.
Не единственный, но ты прав сейчас не воссоздам. А эксперементировать лень, да и некогда(хотя по моему это одно и тоже). Но если вдруг(обещенного три года ждут) - вышлю. -------------------- Как слышим, так и пишим. Истина где-то там... |
||||||
|
|||||||
| p0s0l |
|
|||
![]() Г-н Посол ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 3668 Регистрация: 13.7.2003 Где: 58°38' с.ш. 4 9°41' в.д. Репутация: 58 Всего: 112 |
Я говорил, что странно то, что у тебя размер неправильно определялся в вызываемой процедуре. Хотя определяется-то он в вызывающей... Ну да ладно... Всё равно без багов никуда. Хотя многие баги при ближайшем рассмотрении оказываются и не багами... -------------------- С уважением, г-н Посол. |
|||
|
||||
| Girder |
|
||||
![]() Лентяй 2 ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1993 Регистрация: 12.5.2004 Репутация: 31 Всего: 155 |
Абсолютно верно! Кто с этим спорит! см.выше:
-------------------- Как слышим, так и пишим. Истина где-то там... |
||||
|
|||||
| Kesh |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2488 Регистрация: 31.7.2002 Где: Германия, Saarbrü cken Репутация: 4 Всего: 54 |
p0s0l Да ничего я не пытался тебе доказать... Мне просто интересно стало... Вот торкнуло меня на передачу параметров и все тут... Сейчас вот действительно склоняюсь к твоим словам... Просто до послееднего момента у меня была мысль, что параметр для edx, тот который @DynArrayHigh, cоздается в самой программе при инициализации, а там уже хранится как переменная... Переубедил... Респект...
-------------------- ![]() |
|||
|
||||
![]()
|
| Правила форума "Delphi: Общие вопросы" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |