Страница 1 из 2

Как заполнить массив в дочернем модуле?

СообщениеДобавлено: 27.03.2013 23:06:07
vitaly_l
Есть, главный модуль, в uses которого - указан дочерний модуль.
В главном модуле - создан сложный массив, с множеством под-массивов.

:?: Как заполнить массив с множеством под-массивов из главного модуля в подчинённом ему дочернем модуле? :?



PS: Всем кто прочитает, а тем более поможет - отличного настроения! :cry:


.

Re: Как заполнить массив в дочернем модуле?

СообщениеДобавлено: 27.03.2013 23:46:23
absdjfh
Вариант 1: перенести данные в дочерний модуль.
Вариант 2: экспортировать данные из главного модуля и описать декларацию внешней переменной в дочернем.
Пользуйтесь общепринятыми терминами, а не своими.

Re: Как заполнить массив в дочернем модуле?

СообщениеДобавлено: 28.03.2013 00:23:49
vitaly_l
Спасибо за ответ, но к сожалению, в ответе - недостаточно данных.
absdjfh писал(а):Пользуйтесь общепринятыми терминами, а не своими.

Я стараюсь, однако, к сожалению - не все термины ещё знаю.
absdjfh писал(а):перенести данные в дочерний модуль.

Именно этого я и не умею делать. Из дочернего в главный модуль умею передавать данные, а на наоборот нет. Как это делается?
absdjfh писал(а):экспортировать данные из главного модуля и описать декларацию внешней переменной в дочернем

Возможно это то что я ищу. Суть в том я не умею экспортировать(или переносить) данные из главного модуля. Как это делается?



.

Re: Как заполнить массив в дочернем модуле?

СообщениеДобавлено: 28.03.2013 05:59:34
SSerge
У вас принципиально неправильный подход.

Объявления вашего массива и переменные, соответствующие вашему массиву должны быть либо в как вы его называете "дочернем модуле", либо в отдельном unit, который есть в uses как основной программы, так и "дочернего модуля".

Иначе потом сами не найдете, где вы чего определили. То есть, технические средства есть, чтобы переменную из program описать в каком-то unit, но делать это логически неправильно.

И, опять же, определяя глобальную переменную в unit, вы закладываете мину замедленного действия. Правильный путь объектно-ориентираванного программирования говорит о том, что глобальных переменных вообще не должно быть - любая переменная должна быть обёявлена только внутри описания класса и принадлежать экземпляру этого класса, чтобы потом не искать мучительно "откуда она взялась".

Re: Как заполнить массив в дочернем модуле?

СообщениеДобавлено: 28.03.2013 08:52:31
Oleg_D
Попробуйте вынести глобальные данные, используемые в нескольких модулях, в отдельный модуль и подключить его через uses.
Вот пример.
Код: Выделить всё
program Test_Main;  // Главная программа
uses
  Test_Unit,  // модуль с процедурами
  Test_Data;  // модуль с данными
begin
  Test_Data.PublicVar:= 1;
  Test_Unit.Clear;
  Write(Test_Data.PublicVar);
  Readln;
end.


Код: Выделить всё
unit Test_Data;  // Модуль с данными
interface
var PublicVar : integer;
implementation
end.


Код: Выделить всё
unit Test_Unit;  // модуль с процедурами
interface
  procedure Clear;
implementation
  uses Test_Data;
procedure Clear;
begin
  Test_Data.PublicVar:=0;
end;
end.


Префиксы с именами модулей тут не обязательны, но для наглядности не помешают.

Re: Как заполнить массив в дочернем модуле?

СообщениеДобавлено: 28.03.2013 09:59:53
alexey38
SSerge писал(а):И, опять же, определяя глобальную переменную в unit, вы закладываете мину замедленного действия. Правильный путь объектно-ориентираванного программирования говорит о том, что глобальных переменных вообще не должно быть - любая переменная должна быть обёявлена только внутри описания класса и принадлежать экземпляру этого класса, чтобы потом не искать мучительно "откуда она взялась".

Учитывая, что паскалевские модули - это тоже элемент структурного программирования, с элементами ООП, то ничего плохого в глобальных переменных нет. Наличие класса в единственном экземпляре - это тоже не самый хороший способ, по целому ряду причин.

Принципиально важно, прежде чем начать программировать, сформулировать и продумать постановку задачи. Очень много программистов вначале пишут код, а потому думают, в итоге рождается ужасная структура классов. Среди ответов на вопросы к постановке задачи: какие данные в каком числе экземпляров могут быть, какая их смысловая взаимосвязь. Итогом таких измышлений должна стать как раз структура данных. Работать нужно так, чтобы если вас через 20 лет после окончания проекта ночью разбудили и спросили где описана некая переменная, то Вы сходу должны дать ответ. Если это так, значит структурное и объектное программирование было освоено правильно. Если человек для ответа хочет посмотреть в проект, значит он плохо спроектировал структуру программы. Структура программы должна соответствовать логике мышления.

В данном случае, если постановкой задачи некие данные могут быть только в единственном экземпляре (не 2, не 0, а 1 и только 1), то применение глобальных переменных вполне оправданное решение. Во всех других случаях нужно делать классы. Глобальные данные и данные в объектах нужно выносить в отдельный модуль, Oleg_D выше очень наглядно показал как это нужно делать. Единственное, что нужно вместо названия модуля Test_Data, использовать сразу такое, которое и через 20 лет будет в памяти, т.е. совпадающее со смыслом из постановки задачи.

Re: Как заполнить массив в дочернем модуле?

СообщениеДобавлено: 28.03.2013 10:43:45
Oleg_D
alexey38 писал(а):Единственное, что нужно вместо названия модуля Test_Data, использовать сразу такое, которое и через 20 лет будет в памяти, т.е. совпадающее со смыслом из постановки задачи.

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

Re: Как заполнить массив в дочернем модуле?

СообщениеДобавлено: 28.03.2013 13:07:07
vitaly_l
SSerge писал(а):И, опять же, определяя глобальную переменную в unit, вы закладываете мину замедленного действия.

Вот только не надо красивых фраз, я достаточно хорошо знаю например PHP и там с этим проблем нет. Заметьте: ДАЖЕ СКРИПТЫ - отлично и быстро работают. То что, это нестандартный в Вашем понимании подход: с этим я согласен, т.к. Вас обучали именно так программировать. И я не спрашиваю: хорошо это или плохо?

Я спрашиваю: :?: Как в главном модуле объявить переменную, которую будет видно в "подчинённых" юнитах? Если ВЫ знаете,
то напишите ответ, к ответу можете приложить свою точку зрения, если она будет адекватной, с точки зрения решения моей задачи, я обязательно к Вашему мнению прислушаюсь.


Oleg_D писал(а):Попробуйте вынести глобальные данные, используемые в нескольких модулях, в отдельный модуль и подключить его через uses.
СПАСИБО - БОЛЬШОЕ; ЧЕЛОВЕЧЕСКОЕ :P .

alexey38 писал(а): Структура программы должна соответствовать логике мышления.

Если Вы сможете описать логику мышления, то Вы будете первым из ныне-живущих. В смысле над этим бьются уже много десятков и даже сотен лет, но толком никто не может сказать: Что такое сознание?
Oleg_D писал(а):Совсем без глобальных переменных не обойтись, это так. Но надо стремиться свести их количество к минимуму, а данные передавать через параметры процедур и функций. Но всё это опыт, опыт и опыт.
При передаче, через параметры процедур и функций - тратятся громадные ресурсы. Каждое обращение к процедуре/функции - это уже, колоссальная затрата времени процессора. На самом деле всё зависит от задачи. Поясните почему Вы полагаете что глобальные переменные плохо?

Re: Как заполнить массив в дочернем модуле?

СообщениеДобавлено: 28.03.2013 13:40:12
Oleg_D
Ув. vitaly_l, я рад, если помог хоть чем-то. Поскольку с вашим проектом не знаком,это пока всё, что могу.

Раз вы писали на PHP, стало быть в программировании уже не новичок, но в Паскале свои особенности.
PHP -- интерпретируемый язык с динамической типизацией, а Pascal -- компилируемый язык со статической типизацией.
В первом всё ворочается действительно весьма медленно, поскольку накладные расходы на интерпретацию, создание и уничтожение переменных очень велики.
В Паскале память для локальных переменных и параметров отводится в стеке автоматически, что почти не требует расхода времени, поскольку архитектура любого современного процессора заточена под это.

Почему нежелательны лишние глобальные переменные? Потому, что они доступны из любой точки программы, и в сложных программах трудно отследить, какой модуль или процедура на них действуют. Это запутывает проект и снижает надёжность программы.
Что нужно объявлять глобальным? То, что требуется на всех этапах работы программы: от начала до конца. Все временные данные делают локальными.
Если глобальные данные нужны лишь внутри одного модуля, их объявляют в секции реализации. А если в они нужны и в других модулях, то в секции интерфейса (как в моём примере выше).

Re: Как заполнить массив в дочернем модуле?

СообщениеДобавлено: 28.03.2013 14:07:08
vitaly_l
Oleg_D писал(а):В Паскале память для локальных переменных и параметров отводится в стеке автоматически, что почти не требует расхода времени, поскольку архитектура любого современного процессора заточена под это.

Значит разницы нет?!... попробуем сломать Ваше утверждение.... Из Ваших слов следует, что: скорость обращения к данным через функцию, в которой локальные переменные и скорость обращения к глобальной переменной - одинаковы. Не могу согласиться, т.к. обращение к функции - занимает время. А вот передача через переменные функции, которые объявляются в скобках, справа от названия функции - насколько сильно занимают процессор и тратят время? Наверняка там громадные временные рамки при обращении в 100000 итераций? Более того мы утверждаем что Энштейн - заблуждался в своих расчётах. Хотите оспорить решение Академии Искусств? Для этого, придётся признать программирование - одним из видов Искусства. Таким образом властью художника - объявляю отныне и навсегда: Программирование - это Искусство!
Oleg_D писал(а):Это запутывает проект и снижает надёжность программы.
Искусство - сложная вещь. В Искусстве - всё зависит от изначальной логики программы (я так думаю), но я художник - представитель наидревнейшего Искусства планеты. Художникам свойственно преувеличивать и "ложно" трактовать естественные для большинства факты. Однако я твёрдо уверен, что надёжность программы - зависит от аккуратности программиста и глобальные переменные здесь ни при чём.
Oleg_D писал(а):Если глобальные данные нужны лишь внутри одного модуля, их объявляют в секции реализации. А если в они нужны и в других модулях, то в секции интерфейса (как в моём примере выше).
Ну вот.. Вы противоречите сами себе. Т.к. естественно мне априори нужны данные, которые я хочу использовать в нескольких модулях, причём и кстати - постоянно и очень часто. Ещё раз спасибо за Ваш пример.

Если ЕЩЁ как-то можно объявлять глобальные переменные в главном модуле, так чтобы их было видно в подчинённых - пишите.

Re: Как заполнить массив в дочернем модуле?

СообщениеДобавлено: 28.03.2013 14:46:50
SSerge
vitaly_l писал(а):Вот только не надо красивых фраз, я достаточно хорошо знаю например PHP и там с этим проблем нет


Ну так делайте как в PHP. :mrgreen:
То есть - в единственном модуле программы - инклюды текстов ваших объектов, функций и т.п. Директива емнип {$i имяфайла}
Зачем вам пошлые uses?
Или вы реально не понимаете разницы между включением текста из другого файла и использованием модуля.

Кстати, специально для вас.
Можете поместить uses на "главный" модуль в разделе implementation вашего дочернего модуля. Даже какое то время имеет шансы правильно работать. А дальше... Но вы же не ищете правильных путей, не так ли? :!:

Re: Как заполнить массив в дочернем модуле?

СообщениеДобавлено: 28.03.2013 14:49:09
svk12
vitaly_l писал(а):Есть, главный модуль, в uses которого - указан дочерний модуль.

vitaly_l писал(а):Как в главном модуле объявить переменную, которую будет видно в "подчинённых" юнитах?


В uses "подчинённых" модулей прописать "главный".
Но они должны быть прописаны в разных секциях(interface/implementation).

Re: Как заполнить массив в дочернем модуле?

СообщениеДобавлено: 28.03.2013 15:17:31
vitaly_l
SSerge писал(а):Но вы же не ищете правильных путей, не так ли?

SSerge писал(а):в разделе implementation вашего дочернего модуля...

svk12 писал(а):Но они должны быть прописаны в разных секциях(interface/implementation).

:arrow: СПАСИБО!

:idea: :?: Ещё есть способы передачи данных из главного модуля в модуль подчинённый?



.

Re: Как заполнить массив в дочернем модуле?

СообщениеДобавлено: 28.03.2013 15:44:29
alexey38
vitaly_l писал(а):Если Вы сможете описать логику мышления, то Вы будете первым из ныне-живущих. В смысле над этим бьются уже много десятков и даже сотен лет, но толком никто не может сказать: Что такое сознание?

Речь не идет чтобы в программе описать человека, его сознание и мышление. Речь идет чтобы программу писать максимально близко к своим рассуждениям о самой задаче. Поэтому нужно вначале много подумать о самой задаче, а только после этого начинать ее писать. Если в Ваших рассуждениях возникает некий объект, значит под него нужно предусмотреть класс. А если в Ваших рассуждениях нет вызова функции с кучей параметров, то не нужно этого делать, даже если некоторые Вам это советуют из каких-то теоретических соображений.

Проблема в том, что многих учат программировать оторвано от анализа самой задачи. Поэтому многие исходя из классики программирования вначале создают некую классическую структуру классов, а затем начинают ее "за уши" притягивать к реальной задаче. Такое не нужно делать. Поэтому я Вам не советую создавать классы там, где они не нужны и где достаточно использовать глобальную переменную. Но если создаете глобальную переменную, то не называйте ее очень кратко, типа i,j,x,y и т.п., т.к. доступ к ним есть много откуда и можно ошибочно перетереть значение там, где не нужно было. Поэтому называйте модули, глобальные переменные и процедуры длинно, максимально привязываясь в их фактическому наименованию. Тогда и через 20 лет Вы быстро вспомните название переменной по ее смысловому названию.

Добавлено спустя 8 минут 20 секунд:
vitaly_l писал(а):Ещё есть способы передачи данных из главного модуля в модуль подчинённый?

В паскале и других языках нет понятия подчиненности модулей. В этом смысле все модули равны, и есть общие правила доступа к переменным, типам и процедурам описанных в другом модуле. Главный модуль отличается от неглавного только тем, что имя exe-файла соответствует имени этого модуля, а также тем, что секция begin end (аналог initialization) будет там выполняться позже секций initialization всех других модулей. В остальном имеем равенство.

Поэтому имеем общее правило, что для доступа к переменным описанным в модуле ХХХХХ, нужно в строке uses написать ХХХХХ.

Другой способ, это когда Вы вызываете функцию из модуля ХХХХХ, то в ее параметрах перечисляете все, все, все, что ей может понадобится. Если таких данных мало, то все хорошо, например, вызывая функцию y:=sin(x), у нас не вызывает сомнение в указании в параметрах Х, хотя мы бы могли объявить глобальную переменную var Sin_X:Double; и в коде писать Sin_X:=x;y:=sin; Но это было бы менее понятно и наглядно.

Re: Как заполнить массив в дочернем модуле?

СообщениеДобавлено: 28.03.2013 15:58:47
vitaly_l
alexey38 писал(а):Речь идет чтобы программу писать максимально близко к своим рассуждениям о самой задаче.

От меня потребовали - излагать вопросы, в соответствии с принятыми стандартами. Я это понимаю и принимаю; более того стараюсь придерживаться принятых стандартов и понятий, т.к. иначе будет хаос. Так вот - невозможно написать программу, хотя-бы на йоту близкую к мышлению, пока не знаком с понятием сознание, т.к. в мышлении человека - всегда участвует сознание. Бессознательное - это отсутствие мышления. Программа имеет - сознание? Предполагаю, что - нет. Соответственно невозможно построить программу, соответствующую логике человеческого мышления, до тех пор пока не идентифицировано сознание.
:roll: Будете спорить?

alexey38 писал(а):Проблема в том, что многих учат программировать оторвано от анализа самой задачи.

Проблема в том что учат, как правило те кто никогда не программировал. Все системы обучения отстают от практики - это признают даже в МГУ и других довольно сильных образовательных учреждениях. Я просто недавно присутствовал на реальном форуме меду лекторами и производителями, лекторы там это многократно акцентировали. Но проблемму решить не могут, т.к. это гипер-сложно.
alexey38 писал(а):я Вам не советую создавать классы там, где они не нужны и где достаточно использовать глобальную переменную. Но если создаете глобальную переменную, то не называйте ее очень кратко, типа i,j,x,y и т.п., т.к. доступ к ним есть много откуда и можно ошибочно перетереть значение там, где не нужно было. Поэтому называйте модули, глобальные переменные и процедуры длинно, максимально привязываясь в их фактическому наименованию.

Полностью солидарен и благодарен в отношении сказанного.


.