Форум: "Потрепаться";
Текущий архив: 2002.08.08;
Скачать: [xml.tar.bz2];
Вниз
К вопросу об индексированных метках Найти похожие ветки
← →
DeepProg (2002-07-05 18:15) [0]Проблема: в приложении по ряду объективных причин не могу обойтись без goto. Но в той архитектуре кода, который я написал происходит зацикливание (из-за переходов по 2 взаимосвязанным меткам).
Если бы я мог присвоить одной из меток индекс (что-нибудь вроде свойства tag у компонент), который бы стал контрольным счетчиком, то проблема была бы разрешена.
Вопрос: 1.Можно ли присвоить метке индекс?
2.Если это возможно, то как это сделать?
← →
Skier (2002-07-05 18:19) [1]>DeepProg
> в той архитектуре кода, который я написал происходит зацикливание
>
Скорее всего у тебя не очень хорошая архитектура кода.
← →
Viewer (2002-07-05 18:22) [2]И что есть метки ?
← →
DeepProg (2002-07-05 19:05) [3]Описываю задачу конкретнее
Юзер вводит число объектов, которые необходимо начертить.
Приложение(его задача рисовать) в зависимости от введенного значения должно нарисовать именно столько объектов, причем по строго заданным координатам.
Координаты каждого объекта не могут вычисляться случайным образом, т.е. для кажого объекта координаты задаются отдельно. Сама же команда построения одинакова для всех объектов(это, я надеюсь, пояснять не нужно), поэтому ее нецелесообразно впихивать в операторные скобки вычисления координат каждого объекта (так как эта команда вовсе не одна коротенькая строчка).
Циклом здесь не вывернешься, а потому для вычисления координат конкретного объекта приходится использовать конструкцию
if i<=n then {считаем координаты}. Здесь i:integer - счетчик, n:integer - число объектов. i<=n ставится как раз затем, чтобы прога чертила нужное число объектов, а не один из них, который шел бы n-ным номером. {Если напрячься, то понять это можно :)}
А вот команду к построению вынести бы тогда в конец кода и передавать туда управление goto, установив там метку, да только нет такого опеератора goback? который возвращался бы после выполнения участка метки назад: туда, откуда было передано управление.
Если что-нибудь поняли, то, с нетерпением, жду ответов. :))
Да, ПРО ТЕ ДВЕ МЕТКИ ПОХОЖЕ ПРИДЕТСЯ ЗАБЫТЬ, и про их индексы, может быть. тоже, потому что я так и не смог себе представить как все это будет выглядеть :((((.
← →
Skier (2002-07-05 19:13) [4]>DeepProg
Я, настоятельно советую, Вам, батенька, прежде чем
браться за программирование в Delphi,почитать Гради Буча.
Особенно внимательно прочитайте про классы !
← →
Shrek (2002-07-05 19:17) [5]Такие вопросы нецелесообразно комуто задавать. Если делаеш колесо то делай это сам.
← →
Dimka Maslov (2002-07-05 19:28) [6]а циклы repeat..until, while..end, операторы break и continue, продедура Abort c операторами try except on, для чего были придуманы? Метки в современной программе это атавизм и с ними надо бороться. А вот чтобы их побороть нужно знать операторы. А чтобы их узнать нужно читать литературу.
← →
DiamondShark (2002-07-05 19:42) [7]Уважаемый DeepProg!
Смею вас заверить, что никакие goto и метки в структурированном языке не нужны. Существует метод формального преобразования алгоритмов, при котором получается хорошо структурированная программа. Единственное условие -- существование алгоритма как такового, представленного в виде графа. Метод берет свое начало из теории конечных автоматов. Если вам интересно, свяжитесь со мной лично.
← →
DeepProg (2002-07-05 19:44) [8]
> Skier
> Гради Буча
Неужели. И как называется это чудо программерской мысли. Попробую достать.
← →
TTCustomDelphiMaster (2002-07-05 19:45) [9]А такие вещи как Procedure и Function нельзя использовать?
← →
Cobalt (2002-07-05 23:17) [10]>TTCustomDelphiMaster © (05.07.02 19:45)
Поддерживаю. (По-моему, вопрос из разряда тех, которыми Хавк поначалу заваливал форумы;)
← →
kull (2002-07-06 00:41) [11]Да, любопытно!
Считать объекты с помошью меток...
← →
NailMan (2002-07-06 02:29) [12]DiamondShark>Смею вас заверить, что никакие goto и метки в DiamondShark>структурированном языке не нужны
несогласен, иногда полезны(не необходимы, а полезны)
Как например в моей игрухе - наглядно и без гемора.
To DeepProg>
ты чо на Асме пишешь или на Дельфе? А, имхо, Procedure и Function для рисования придумать не судьба?
← →
DiamondShark (2002-07-06 14:05) [13]DeepProg
Мышление, испорченное басиком.
NailMan
>>
несогласен, иногда полезны(не необходимы, а полезны)
Как например в моей игрухе - наглядно и без гемора.
<<
Ну, соглашаться или не соглашаться -- личное дело. За советскую власть никто не агитирует. А метод получения нормального структурированного кода существует.
Всем знакомо понятие граф-схема алгоритма, все в школе учились. Такой граф рисовать легко и приятно -- этакий полет фантазии. И представить таким образом можно любой алгоритм, практически сочиняя его на лету. Беда в том, что закодировать такой граф "в лоб" в общем случае не получится. И либо приходится дополнительно повозится с декомпозицией или преобразованием графа, выделяя элементарные структуры, либо код превращается в "макароны" из перепутанных взад и вперед goto.
Однако, произвольный граф алгоритма можно рассматривать как граф состояний абстрактного конечного автомата. Испльзуя всего три понятия: состояние, функция перехода, функция выхода и формальную процедуру можно построить реализацию автомата. Метод изначально был придуман для реализации реальных автоматов "в кремнии", поэтому он дает весьма эффективную реализацию. А так как применяется формальная процедура, то пользоваться ей можно даже не особо "въезжая" в смысл происходящего. К полученному формальному решению можно далее применить частные методы "по месту", получив еще более эффективное решение. И все получается "наглядно и без гемора".
К сожалению, не могу здесь привести более подробное описание, так как для этого требуется воспроизвести несколько картинок и таблиц, но заинтересовавшимся могу ответить лично.
← →
iZEN (2002-07-06 16:10) [14]Для DeepProg © (05.07.02 18:15).
Может это похоже на ваш алгоритм:
program draw;
type
TFigureKind = (Circle, Oval, Square, Triangle);
TFigure = record
kind: TFigureKind;
x: Real;
y: Real;
end;
procedure GenerateCoordinates(var shape: TFigure;);
(* Вычисляем новые координаты фигуры *)
begin
if (shape.kind = Circle) then begin
shape.x := shape.x * 10;
shape.y := 20;
end;
if (shape.kind = Oval) then begin
shape.x := 15;
shape.y := 42;
end;
if (shape.kind = Square) then begin
shape.x := shape.x + 11;
shape.y := shape.y - 32;
end;
if (shape.kind = Triangle) then begin
shape.x := shape.x - 1;
shape.y := shape.y + 2;
end;
end;
procedure ShowFigure(shape: TFigure);
(* Рисуем фигуру *)
begin
.....
end;
var
i, n: Integer;
NewShape: TFigure;
begin
Write("Введите число фигур: ");
ReadLn(n);
i := 1;
while (i <= n) do begin
(* Здесь рисуем одни треугольники *)
NewShape.kind := Triangle;
NewShape.x := 10;
NewShape.y := 15;
GenerateCoordinates(NewShape);
ShowShape(NewShape);
end;
end.
← →
kull (2002-07-07 01:15) [15]
>
> procedure ShowFigure(shape: TFigure);
> (* Рисуем фигуру *)
> begin
> .....
> end;
А здесь что опять case устраивать?
ООП подход:
type
TFigure = class
...
procedure Draw(const x,y: Integer); virtual; abstract;
constructor Create; virtual;
end;
TFigureClass = class of TFigure;
TCircle = class(TFigure)
...
procedure Draw(const x,y: Integer); override;
end;
TOval = class(TFigure)
...
procedure Draw(const x,y: Integer); override;
end;
TSquare = class(TFigure)
...
procedure Draw(const x,y: Integer); override;
end;
TTriangle = class(TFigure)
...
procedure Draw(const x,y: Integer); override;
end;
procedure ShowFigure(const shape: TFigureClass;const x,y: integer);
(* Рисуем фигуру *)
begin
With shape.Create do
begin
Draw(x,y);
Free;
end;
end;
begin
Write("Введите число фигур: ");
ReadLn(n);
i := 1;
while i <= n do
(* Здесь рисуем одни треугольники *)
ShowFigure(TTriangle,10,15);
end.
Если появится еще один класс фигур, не надо вставлять во всех местах case или if.
← →
iZEN (2002-07-07 01:30) [16]/**kull © (07.07.02 01:15):
>
> procedure ShowFigure(shape: TFigure);
> (* Рисуем фигуру *)
> begin
> .....
> end;
А здесь что опять case устраивать?
*/
Да, видимо придётся. Кроме того, нужно ещё организовать опрос пользователя насчёт вида фигур, которые он хочет получить (Окружности, Овалы, Квадраты, Треугольники).
Вы обратили внимание, что я не применял ООП-парадигму програмирования. Это я сделал специально для того, чтобы человек[DeepProg] уяснил суть структурного программирования на Pascal, ведь он не в ладах именно с этой методикой построения программ.
Относительно вашего ООП-алгоритма скажу, что объект Фигура должен полностью инкапсулировать свои данные, но почему-то у вас получается "наизнанку":
....
(* Здесь рисуем одни треугольники *)
ShowFigure(TTriangle,10,15);
....
и
procedure ShowFigure(const shape: TFigureClass;const x,y: integer);
(* Рисуем фигуру *)
begin
With shape.Create do
begin
....
Это работает, не спорю, но дизайн, мягко говоря, хромает. Конечно, это только моё личное мнение.
Изучайте паттерны проектирования.
← →
kull (2002-07-07 01:55) [17]
> Относительно вашего ООП-алгоритма скажу, что объект Фигура
> должен полностью инкапсулировать свои данные, но почему-то
> у вас получается "наизнанку":
>
> ....
> (* Здесь рисуем одни треугольники *)
> ShowFigure(TTriangle,10,15);
> ....
Что-то я не понял, где же здесь нарушена инкапсуляция?
Фигура рисует сама себя, но она не знает где ее хотят нарисовать.
Откуда она по вашему узнает свои координаты?
> А здесь что опять case устраивать?
> */
>
> Да, видимо придётся.
Прийдется и не в одном месте, а если классы использовать, то про процедуры типа ShowFigure и GenerateCoordinates я вообще могу забыть:
type
TSuperFigure = class(TFigure)
...
procedure Draw(const x,y: Integer); override;
end;
begin
...
ShowFigure(TSuperFigure,10,15);
И не надо никаких case...
К тому же насчет хромающего дизайна:
ShowFigure - это просто остатки былой роскоши, прекрасно и без нее обойтись можно:
var
shape: TFigureClass
begin
...
shape.Draw(10,15);
> Изучайте паттерны проектирования.
Спасибо за совет, но этим я как раз я сейчас занимаюсь.
(Э.Гамма Р.Хелм Р.Джонсон Дж.Влиссидес
"Приемы объектно-ориентированного проектирования")
← →
kull (2002-07-07 02:40) [18]
> var
> shape: TFigureClass
> begin
> ...
> shape.Draw(10,15);
Вот здесь-то я и налажал, вот так надо:
var
shape: TFigure;
begin
...
shape.Draw(10,15);
Хы... :)
← →
iZEN (2002-07-07 07:37) [19]/**kull:
<...>
> А здесь что опять case устраивать?
> */
>
> Да, видимо придётся.
Прийдется и не в одном месте, а если классы использовать, то про процедуры типа ShowFigure и GenerateCoordinates я вообще могу забыть:<...>
*/
Да, это так. Этим и отличается процедурное программирование от ООП.
Кстати, в вашем алгоритме объекты Фигур не имеют состояния. Это -- так называемые stateless-объекты. Они полностью повторяют функциональность использования процедур, то есть они по сути -- "интеллектуальные" процедуры. Вот.
Что ж, такой код тоже имеет право на жизнь, не мне судить :), главное -- это решение поставленной задачи наиболее изящными и простыми способами. В данном случае, У вас это получилось лучше чем у меня. Но я сомневаюсь в том, что DeepProg понял ваш алгоритм (не тот уровень знаний ;) ).
← →
DeepProg (2002-07-13 14:30) [20]>iZEN
> не тот уровень знаний
Смотри, не нарвись на бомбу...
Страницы: 1 вся ветка
Форум: "Потрепаться";
Текущий архив: 2002.08.08;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.006 c