![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Ошибка в delphi 7 [D7, WinXP]
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]Спасибо!