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. Хотя считает правильно в целом.


begin...end   (2004-11-18 19:05:00) [61]


> [77] Gero ©   (18.11.04 19:01)

Да вот - видишь ли, надоело уже терпеть.
Неприятно, знаешь ли, когда дураком выставляют.
Особенно, если невнимателен (мягко сказано) на самом деле - не я.
Странно, правда?


Gero   (2004-11-18 19:01:00) [62]


> begin...end ©

Алексей, зачем провоцируешь?
Може хватит?


Gero   (2004-11-18 18:59:00) [63]


> если даже begin...end замечает ошибки в моем примере, то
> их действительно просто заметить

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

Иногда удобнее while, иногда for, иногда удобнее с Break, иногда без него.
Зачем вбивать себе в голову какие-либо ограничения?


begin...end   (2004-11-18 18:58:00) [64]


> [69] Defunct ©   (18.11.04 18:05)


> А тут приходит begin..end и пытается мне открыть какую-то
> истину, что с break код выглядит лучше.

1. Куча программистов использует Break в своей практике. А тут приходит Defunct и пытается открыть какую-то истину, что без Break код выглядит лучше. Не забывая при этом допустить элементарнейшую ошибку.
2. Человек учится работать с CompareMem и пытается сравнить две строки с помощью этой функции. Посетители форума дают ему советы, что сравнить можно и с помощью CompareMem, но только немножко не так. А тут приходит Defunct и говорит: строки можно сравнивать с помощью операции "=".
http://www.delphimaster.ru/cgi-bin/forum.pl?id=1100710585&n=0
3. Человек спрашивает: "Как удалить файл в корзину?". Посетители форума советуют ему воспользоваться функцией SHFileOperation. А тут приходит Defunct и говорит, что, дескать, Корзина - это приблуда для дураков, а Вам нужно просто удалить файл с помощью DeleteFile. И термин "удалить в Корзину" - он, видите ли, некорректен. (Ветка, к сожалению, уже ушла в архив.)
4. Приходит Defunct и делает утверждение. Посетитель форума указывает ему, что оно неверно. Defunct отвечает, что Вы, дескать, человек твердолобый, и вот не поняли, что утверждение моё обобщать на явления дальше носа Defunct'а, оказывается, нельзя. (Ветка, к сожалению, уже ушла в архив.)


Defunct   (2004-11-18 18:51:00) [65]

> Но, после этого всего, дайте ответ на вопрос: где легче допусить ошибку в моём коде или в вашем?

Ошибку одинаково легко допустить и там и там.
А вот заметить ошибку, IMHO проще там где нет break.

> Да ладно вам по пустякам кашу заваривать.

А разве я завариваю кашу, объективно оцените ситуацию, посмотрите на посты begin...end [72],[73]. Кстати, Gero, это подтверждает первую часть ответа, если даже begin...end замечает ошибки в моем примере, то их действительно просто заметить.


begin...end   (2004-11-18 18:38:00) [66]


> [70] Defunct ©   (18.11.04 18:15)


> while (A[i]<>S) and (i<Length(A)) do inc(i);

Я прошу прощения - Вы притворяетесь, или действительно не понимаете?

Сделайте доброе дело: опубликуйте где-нибудь список Ваших программ, написанных, вероятно, в том же духе, для того, чтобы ими кто-нибудь случайно не воспользовался. А то - мало ли что, знаете ли.


Gero   (2004-11-18 18:35:00) [67]


> begin...end ©

> Defunct ©

Да ладно вам по пустякам кашу заваривать.

> Defunct ©   (18.11.04 18:05)

Понимаете, что для того, чтобы сделать код рабочим, понадобилась куча исправлений.
И одну ошибку в коде вы даже не заметили.
Конечно, каждый мог не заметиь, дело не в вас.
Но, после этого всего, дайте ответ на вопрос: где легче допусить ошибку в моём коде или в вашем?


begin...end   (2004-11-18 18:35:00) [68]


> [69] Defunct ©   (18.11.04 18:05)


> Неужели Вы не понимаете, мне этот код вообще не нужен.

Я понимаю, что он Вам не нужен. Но я думал, что Вы отвечаете за свои слова. И если Вы приводите пример кода, который НЕ РАБОТАЕТ при условии, что его переделали из "абстрактного" в "неабстрактный", то после выяснения этого печального обстоятельства Вы поймёте свою ошибку и признаете её. Хотя справедливости ради надо сказать, моя надежда на это была весьма слабой.

А теперь я позволю себе показать, как изменяются переменные в коде из [68], сделанном на базе Вашего.

До прохода цикла:I = 0. При вычислении первой части условия повторения цикла происходит обращение к СУЩЕСТВУЮЩЕМУ элементу массива Arr, а именно Arr[0]. Второе условие, т.е. I <= High(Arr), истинно, т.к. 0 <= 1.

После первого прохода цикла:I = 1. См. предыдущий абзац, с заменой числа 0 на число 1.

После второго прохода цикла:I = 2. Происходит обращение к НЕСУЩЕСТВУЮЩЕМУ элементу массива Arr, а именно Arr[2]. Как говорится, комментарии излишни. Истинность или ложность второго условия продолжения цикла уже никого не интересует.

А теперь, - и что самое интересное! - такая ошибка возникла, скорее всего, именно потому, что for был заменён на while.

На всякий случай поясню, как избежать этой ситуации - надо просто поменять местами NoError(Arr[i]) и (I <= High(Arr)), и не забыть отключить опцию Complete Boolean Eval.

И после этого Вы утверждаете, что while лучше, чем for. Может быть, и лучше, но только не для Вас.


Defunct   (2004-11-18 18:15:00) [69]

> begin...end ©
> Видите ли: если сделать на основе Вашего "абстрактного" кода "неабстрактный", то он тоже не будет работать.

Я вас огорчу, вот абстрактный код[23]:

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


а вот здесь я из него делаю не абстрактный код [53]:

a:array of string;

Function FindS(Const S:String):Integer;
Var
i:Integer;
Begin
i := 0;
while (A[i]<>S) and (i<Length(A)) do inc(i);
if i<Length(A) then Result := i
               else Result := -1
End;


2 begin...end
Обратите внимание, что неабстрактным и рабочим, я его сделал еще до того как вы сегодня проснулись.


Defunct   (2004-11-18 18:05:00) [70]

begin...end ©   (18.11.04 17:39) [68]
> Ваш код перестаёт работать! Чудеса, не правда ли?

Неужели Вы не понимаете, мне этот код вообще не нужен. И мне даже не интересно работает он или нет. То что я хотел показать (без break можно обойтись всегда), я показал.
Я ни разу в программах на Паскале и Delphi, за последние ~10 лет, не использовал ни break, ни goto, ни exit, а continue считал и считаю верхом алогизма (особенно если крутится вложенный цикл). А тут приходит begin..end и пытается мне открыть какую-то истину, что с break код выглядит лучше. Да как хотите, юзайте ваш break, юзайте inline, юзайте continue, пишите все операторы в одну строку. Все равно мы с вами, как вы намекнули, вместе не работаем и мне не придется лицезреть и править ваш код.

> Что-то долго до Вас доходит.
До меня "дошло" вот что.
1. Вам нечем заняться.
2. Вы хотите порадоваться тем, что приперли меня к стенке знаком равенства.
3. Вы не желаете вникнуть в суть дискуссии, вам ведь всего-то для полного счастья надо найти ошибку в абстрактном примере.


begin...end   (2004-11-18 17:39:00) [71]


> [67] Defunct ©   (18.11.04 17:29)


> Мне все равно, что вы считаете. Я и так знаю, что абстрактный
> код не будет работать на практике.

Что-то долго до Вас доходит. Видите ли: если сделать на основе Вашего "абстрактного" кода "неабстрактный", то он тоже не будет работать.

Вот пример:

function NoError(Element: Integer): Boolean;
begin
 Result := Element > 0;
end;

var
 I: Byte;
 Arr: array [0..1] of Integer;
begin
 Arr[0] := 1;
 Arr[1] := 5;
 I := 0;
 while NoError(Arr[i]) and (I <= High(Arr)) do
 begin
   Inc(I)
 end
end.

И здесь применение Вашего кода вызывает ошибку . У Вас есть предположения, почему это так происходит, или Вам нужно пояснить?


Defunct   (2004-11-18 17:29:00) [72]

> Я Вам не коллега.
LOL
"тамбовский волк тебе товарищь" (C)
похвально!

> Я же говорю Вам, что Ваш код не только не соответствует коду Gero, а даже и не работает вовсе

Код Gero тоже не работает, это был абстрактный пример если до вас до сих пор не дошло.

> И он не будет работать даже в том случае, если заменить условие "<" на "<=".

Мне все равно, что вы считаете. Я и так знаю, что абстрактный код не будет работать на практике.

> О какой ошибке Вы говорите? Уж не сделали ли Вы окончательное заключение о деятельности функции IsError по её названию? В таком случае, можно это название изменить.

Измените, если вам полегчает. Тогда и смысл будет другим, тогда на кой черт break?

> P.S. Интересна Ваша манера отвечать на чьи-либо сообщения, при этом переворачивая всё с ног на голову.

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

Мне интересна ваша манера изучения отходов ракетного топлива после того как ракета уже улетела.
PS: А конференция-то была по динамике полета.


begin...end   (2004-11-18 17:20:00) [73]

> Defunct

Небольшая поправка к [65].

Если считать всякие Inc'и само собой разумеющимися, то Ваш код из [23] работает, но некорректно. А после внесения исправлений, указанных Вами же в [63], т.е. замены "<" на "<=", Ваш код перестаёт работать! Чудеса, не правда ли?


begin...end   (2004-11-18 16:58:00) [74]


> [64] Defunct ©   (18.11.04 16:48)


> Набирайте высоту коллега.

Я Вам не коллега.

> Негоже искать истину в inc.

Что-то я Вас не пойму. В [63] Вы утверждаете, что Ваш код соответствует коду Gero. Я же говорю Вам, что Ваш код не только не соответствует коду Gero, а даже и не работает вовсе(последнее - даже если добавить инициализацию и увеличение счётчика). И он не будет работать даже в том случае, если заменить условие "<" на "<=".

> на кой черт проверять какую-то ошибку.

О какой ошибке Вы говорите? Уж не сделали ли Вы окончательное заключение о деятельности функции IsError по её названию? В таком случае, можно это название изменить.

P.S. Интересна Ваша манера отвечать на чьи-либо сообщения, при этом переворачивая всё с ног на голову.


Defunct   (2004-11-18 16:48:00) [75]

begin...end ©   (18.11.04 16:21) [62]

Набирайте высоту коллега. Негоже искать истину в inc.
Лучше поищите истину здесь:
if IsError(Arr[i]) then Break;

на кой черт проверять какую-то ошибку.
смотрите 36.

for i := 0 to High(Arr) do
try
  <Код>
except
  <обработка искл.>  
end;


Defunct   (2004-11-18 16:41:00) [76]

Sicilla   (18.11.04 14:39) [56]

Перечитайте [11] и [14] там указаны возможные ошибки в вашем коде.
Особенно обратите внимание на [14], там IMHO возможная причина неверной работы 3-го цикла.



KSergey ©   (18.11.04 16:08) [61]

Это Gero так считает. Я же считаю, что все там соответствует, за исключением условия < должно быть <=. ну и еще инвертирована функция NoError = not IsError. Но это IMHO мелочи. При проектировании программы, я бы строил соответствующие функции.

> Так что делать тут будем?
А что бы вы хотели делать?
Я придерживаюсь позиции без break можно обойтись всегда. Без break логика программы выглядит более читабельно. Хотя бы потому что выход из цикла всегда в одном и том же месте.

Вот пример с exit, это сродни break:

procedure DoSomthing( SomeObject : TSomeClass);
begin
 if SomeObject = nil then Exit;

 with SomeObject do
 begin
   <Код>
 end
end;

procedure DoSomething( SomeObject: TSomeClass);
begin
 if SomeObject <> nil then
 with SomeObject do
 begin
   <Код>
 end
end;


Что, на ваш взгляд, проще для отладки и выглядит логичнее?
Обратите внимание, что если все без исключения процедуры и функции оформлены без операторов управления, это значительно повышает "гибкочитаемость" программы и такую программу проще отлаживать, т.к. всегда известно где "вход", а где "выход" (даже не нужно читать код). Там где много "входов" и много "выходов" там обычно и проблемы.


begin...end   (2004-11-18 16:21:00) [77]


> [61] KSergey ©   (18.11.04 16:08)

К тому же уважаемый Defunct забыл добавить туда инициализацию и увеличение счётчика (а это влияет на читаемость), т.е.:

i := 0;
while NoError(Arr[i]) and (i<High(Arr)) do
begin
  Inc(i);
 <Код>
end.

Впрочем, этот код (как и оригинальный из [23]) будет, конечно, некорректно работать как в случае {$B-}, так и в случае {$B+}. (Оригинальный код из [23], разумеется, работать вообще не будет.) Кстати сказать, в случае for про подобные директивы можно и вовсе не помнить.

Ну а насчёт удобочитаемости - для меня лично действительно легче понять, что делает такой код:

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

чем код, приведённый выше.


KSergey   (2004-11-18 16:08:00) [78]

2 Defunct

Товарищи втянули вас в обсуждение более сложного случая. Однако вы не ответили на замечание по простейшему коду, приведенному Gero. Позволю себе напомнить:

> [26] Gero ©   (18.11.04 00:16)
>
> > while NoError(Arr[i]) and (i<High(Arr)) do
> > Begin
> >  <Код>
> > end;
>
> Этот код совсем не соответствует моему.

И ведь действительно не соответсвует! Так что делать тут будем? В этом, простейшем случае? Доп. проверку условия вводить? Переставлят местами проверку?


Amoeba   (2004-11-18 15:24:00) [79]


> что касается строки j := num - ini.kol_prov, то мне надо
> было просто узнать знак разности

А зачем его узнавать еще раз? Ведь и j у тебя не изменялся в предыдущем цикле.

P.S.
от прогресса не уйдешь
Я, например, до сих пор сижу на D5 и не вижу для себя достаточно веских причин переходить на более новые версии.


Sicilla   (2004-11-18 15:18:00) [80]

Спасибо!


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

Наверх

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