Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Ошибка в delphi 7 [D7, WinXP]


Страницы:   1 2 3 4 5 6 7

Sicilla ©   (2004-11-17 18:34:00) 

Привет всем. Постваил себе delphi 7 взамен delphi 5. delphi 5 не удалял. И теперь ошибка: при отладке F7 например в переменной i значение 2, а кажет, что там 10 или -5. Хотя считает правильно в целом.


Palladin   (2004-11-18 01:11:00) [101]


> [36] Игорь Шевченко ©   (18.11.04 01:02)

Ну что же Вы так... Мечом то сразу по узлу... :)


Palladin   (2004-11-18 01:04:00) [102]

Ну конечно это не проблема. Если ProceedCommand процедура. Но если это все таки функция, которая возвращает результат выполнения команды? Но не булевский, а, скажем Integer, который потом нужно еще и анализировать и который влияет на выход из тела цикла при определенных условиях...

Кстати, в A) была допущена ошибка. Устройство ведь нужно проверить на готовность перед записью... но в принципе это ерунда, в and это увязывается. Еще момент: вы уверены, что команды выполнятся именно в том порядке в котором они записаны? Я почему то нет... Кто его знает, этот оптимизатор... Ну это тоже черт с ним... Правда ошибку искать потом неудобно будет...

Повторюсь, это ведь простейший пример. На его, так сказать, "оптимизацию" к нестабильной не гибкой форме, у вас ушло времени гораздо больше чем у меня на вариант A)... Как вы думаете... Это хорошо?


Игорь Шевченко   (2004-11-18 01:02:00) [103]

Я бы код организовал следующим образом


 ConnectDevice;
 try
   try
     while true do begin
       ReadCommand;
       ProceedCommand;
       WriteCommand;
     end;
   except
     on E: EDeviceNotConnected do
       ....
 finally
   DisconnectDevice;
 end;


А внутри ReadCommand и WriteCommand написал бы
 
 if not DeviceConnected then
   raise EDeviceNotConnected.Create(...);
 .....
 


Игорь Шевченко   (2004-11-18 00:55:00) [104]

Defunct ©   (18.11.04 00:47) [32]

Код в D отличается от кода А по логике. То есть, гарантировано работает не так, как оригинал. Хотя и более удобочитаем.


> Только за то, что там указывается "полнота" языка паскаль?


Это не "полнота". Такие советы давались на заре программирования или в эпоху структурного программирования. После этого пришли к выводу, что введение операторов управления (Break, Continue, Exit) улучшает удобочитаемость кода.


Defunct   (2004-11-18 00:52:00) [105]

> :) К сожалению ProceedCommand это не функция, результат выполнения не влияет на выход/продолжение цикла.

;)
Это не проблема:

function ProceedCommand:boolean;
begin
 <код процедуры>;
 Result := True
end;


Palladin   (2004-11-18 00:49:00) [106]


> [32] Defunct ©   (18.11.04 00:47)

:) К сожалению ProceedCommand это не функция, результат выполнения не влияет на выход/продолжение цикла.


Defunct   (2004-11-18 00:47:00) [107]

Palladin ©   (18.11.04 00:34) [29]

Соблюдаю последовательность действий:
D)

DeviceConnect;
NoError := True;
Try
 while NoError and DeviceConnected do
   NoError := ReadCommand and ProceedCommand and WriteCommand
Finally
 TryDisconnectDevice;
End;


Игорь Шевченко ©   (18.11.04 00:40) [30]
> Главное в коде - его удобочитаемость
Об этом и речь.
Done - образный пример.
Неужели пример D) менее нагляден чем A) [22]

> Выкинь книгу на помойку. Искренний совет.
Только за то, что там указывается "полнота" языка паскаль?


Palladin   (2004-11-18 00:42:00) [108]

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


Игорь Шевченко   (2004-11-18 00:40:00) [109]


> А я вам гарантирую, что без Break, Continue, Goto, Exit,
> Inline и прочее упомянутое можно запросто обойтись, причем
> всегда. (написано в любой книге по паскалю в разделе операторы).


Выкинь книгу на помойку. Искренний совет.
Главное в коде - его удобочитаемость, а с введением дополнительных переменных типа Done она ухудшается.


Palladin   (2004-11-18 00:34:00) [110]

Нет, чтение команды, исполнение, запись команды.


Defunct   (2004-11-18 00:28:00) [111]

Gero ©   (18.11.04 00:16) [26]
> Потому что нет необходимости.
Я принимаю ваш аргумент.

Тоже самое ("нет необходимости") имеем и в случае с break и continue.

> Невозможно продумать ведь все ньюансы алгоритма наперед, кроме того, возможно его придется править.
А я вам гарантирую, что без Break, Continue, Goto, Exit, Inline и прочее упомянутое можно запросто обойтись, причем всегда. (написано в любой книге по паскалю в разделе операторы).

Palladin ©   (18.11.04 00:17) [27]
Ок, с учетом немедленного выхода:

C)
DeviceConnect;
NoError := True;
Try
while NoError and DeviceConnected do
begin
  if Not ReadCommand then  NoError := False else
  if Not WriteCommand then NoError := False else
  ProceedCommand
end;  
Finally
TryDisconnectDevice;
End;


Palladin   (2004-11-18 00:17:00) [112]

К сожалению если команда не прочиталась нужно немедленно выйти...


Gero   (2004-11-18 00:16:00) [113]


> while NoError(Arr[i]) and (i<High(Arr)) do
> Begin
>  <Код>
> end;

Этот код совсем не соответствует моему.

> Если так рассуждать, то почему бы не использовать Label?
> Язык ведь позволяет. Почему бы не использовать Inline?

Потому что нет необходимости.
Лично у меня нет принципов, будет мне удобнее с Label - сделаю с Label, будет удобнее с Inline - сделаю Inline, так же и Continue, Break, и пр.
Невозможно продумать ведь все ньюансы алгоритма наперед, кроме того, возможно его придется править.
И чтобы не переписывать всю логику работы, порой достаточно просто поставить в нужном месте Break...


Defunct   (2004-11-18 00:13:00) [114]

Palladin ©   (17.11.04 23:53) [22]
> Для моего восприятия A) понятней чем B),

Честно сказать я соглашусь с этим (в вашей реализации B действительно оказался менее наглядным чем A), но я ниже предлагаю вариант C), который IMHO не менее прозрачен чем A), и для моего восприятия более понятен.

C)
DeviceConnect;
NoError := True;
Try
 while NoError and DeviceConnected do
 begin
   if ReadCommand then ProceedCommand;
   if Not WriteCommand then NoError := False
 end;  
Finally
 TryDisconnectDevice;
End;


Defunct   (2004-11-17 23:55:00) [115]

> for i := 0 to High(Arr) do
> begin
>   if IsError(Arr[i]) then Break;
>   <Код>
> end;

> Реализуйте это красивее без Break.

while NoError(Arr[i]) and (i<High(Arr)) do
Begin
 <Код>
end;

> Если язык позволяет - то почему бы не использовать?
Если так рассуждать, то почему бы не использовать Label? Язык ведь позволяет. Почему бы не использовать Inline? Почему бы всю программу не написать на Asm? Почему бы не писать все операторы  в одну строку? Язык ведь и это все позволяет. Точнее не язык, а компилятор.

Я отвечу на все эти вопросы так:
Потому что НЕ используя все это, программа будет выглядеть куда более удобочиемой, и более доступной для понимания. Углядеть логику (алгоритм) программы будет намного проще, соответственно найти возможную ошибку в коде будет намного проще.


Palladin   (2004-11-17 23:55:00) [116]

Упс.. ошибочка... из толпы условий Not нужно поубирать... и из условия While тоже...


Palladin   (2004-11-17 23:53:00) [117]

Можно, еще как можно. Тоже IMHO.

Конструкция с Done не прокатывает в случае с "многозадачным" циклом. Не в том смысле что потоковым или нитевым, а в том что в цикле выполняется задача разбитая на подзадачи. Простейший пример.

A)

DeviceConnect;
Try
While True Do
Begin
 If Not IsDeviceConnected Then Break;
 If Not ReadCommand Then Break;
 ProceedCommand;
 If Not DeviceConnected Then Break;
 If Not WriteCommand Then Break;
End;
Finally
TryDisconnectDevice;
End;

B)
Var
isDone:Boolean;
Begin
DeviceConnect;
Try
While Not isDone Do
Begin
 isDone:=IsDeviceConnected;
 If isDone Then isDone:=ReadCommand;
 If Not isDone Then  ProceedCommand;
 If Not isDone Then isDone:=DeviceConnected;
 If Not isDone Then isDone:=WriteCommand;
End;
Finally
TryDisconnectDevice;
End;

Для моего восприятия A) понятней чем B), да и надежней если придется добавлять код, разбиратся в толпе условий зависящих от установленной ранее булевой переменной. А между прочим это простейший пример, в сложных алгоритмах простой цепочкой условий не обойтись. Так же break сэкономит время выполнения... просто выйдя за цыкл, не проходя толпу условий..


jack128   (2004-11-17 23:51:00) [118]

Gero ©   (17.11.04 23:41) [20]
При отсутствии Goto - это необходимость.  как выполнить <оператор> N раз подряд??(N - переменная)


Gero   (2004-11-17 23:41:00) [119]


> Я все же придерживаюсь позиции, что break и cont. абсолютно
> излишние операторы.

Любой оператор цикла не есть необходимостью.
Все можно сделать через if'ы.


Defunct   (2004-11-17 23:38:00) [120]

Palladin ©   (17.11.04 23:13) [15]

Я все же придерживаюсь позиции, что break и cont. абсолютно излишние операторы.

Ведь никто не мешает построить тело цикла так:

procedure Cycle;
var Done : boolean;
begin
 Done := not <множество условий запуска>;
 while not Done do
 begin
   ...
   Done := <множество условий выхода>
 end;
end;

...
Cycle;


что же касается
> While True Do
то настал мой черед удивляться, т.к. IMHO такое вообще нельзя писать.


Страницы:   1 2 3 4 5 6 7

Наверх

Титульная страница Поиск, карта сайта Написать письмо