Форум: "Основная";
Текущий архив: 2004.06.27;
Скачать: [xml.tar.bz2];
ВнизКомпилятор насчитал 1+1=1. Почему? Привожу код: Найти похожие ветки
← →
AAAlexeyAAA (2004-06-13 19:55) [0]type TPoint = record
X : longint;
Y : longint;
end;
type Tochka = record
ArrayPoint : array of TPoint;
Rastoyanie : array of integer;
end;
var RecArray : Tochka;
Courses : array [1..8] of TPoint=((X:0;Y:-1),(X:1;Y:-1),(X:1;Y:0),(X:1;Y:1),(X:0;Y:1),(X:-1;Y:1),(X:-1;Y:0),(X:-1;Y:-1));
localpoint : TPoint;
begin
RecArray.ArrayPoint[0].X := 1;
RecArray.ArrayPoint[0].Y := 1;
for count:=Low(RecArray.ArrayPoint) to High(RecArray.ArrayPoint) do
begin
For count2:=1 to 8 do
begin
localpoint.X := RecArray.ArrayPoint[count].X + Courses[count2].X;
localpoint.Y := RecArray.ArrayPoint[count].Y + Courses[count2].Y;
------------------
На шаге count=0, count2=4 (координата:(1,1))
localpoint.X = 1, a localpoint.Y = 2. Почему?
Ставлю брейкпоинт. Первое слагаемое 1, второе тоже 1. Сумма =1
В чём проблема?
← →
default © (2004-06-13 20:01) [1]SetLength забыл
← →
AAAlexeyAAA (2004-06-13 20:04) [2]есть...есть он...перед строкой
RecArray.ArrayPoint[0].X := 1;
.............
SetLength(RecArray.ArrayPoint,1);
SetLength(RecArray.Rastoyanie,1);
Проблема в том что он всё считает правильно, кроме координаты 1,1...
Весь перебор Courses верен,..кроме Courses[4]
← →
default © (2004-06-13 20:11) [3]type TPoint = record
X : longint;
Y : longint;
end;
type Tochka = record
ArrayPoint : array of TPoint;
Rastoyanie : array of integer;
end;
var
RecArray : Tochka;
Courses : array [1..8] of TPoint=((X:0;Y:-1),(X:1;Y:-1),(X:1;Y:0),(X:1;Y:1),(X:0;Y:1),(X:-1;Y:1),(X:-1;Y:0),(X:-1;Y:-1));
localpoint : TPoint;
Form1: TForm1;
count, count2: Integer
...
procedure TForm1.Button1Click(Sender: TObject);
begin
SetLength(RecArray.ArrayPoint,1);
SetLength(RecArray.Rastoyanie,1);
RecArray.ArrayPoint[0].X := 1;
RecArray.ArrayPoint[0].Y := 1;
for count:=Low(RecArray.ArrayPoint) to High(RecArray.ArrayPoint) do
begin
For count2:=1 to 4 do
begin
localpoint.X := RecArray.ArrayPoint[count].X + Courses[count2].X;
localpoint.Y := RecArray.ArrayPoint[count].Y + Courses[count2].Y;
end;
end;
Caption := IntToStr(localpoint.X)
end;
вот такой код 2 выводит...
← →
AAAlexeyAAA (2004-06-13 20:21) [4]localpoint.X = 1 (1+1=1)
localpoint.Y = 0 (1+1=0)
:)
← →
AAAlexeyAAA (2004-06-13 20:28) [5]Подскажите хоть "где копать" ?
← →
default © (2004-06-13 20:30) [6]выложи код полностью который работает неверно
← →
AAAlexeyAAA (2004-06-13 20:33) [7]Прошу прощения <<default>>.
Если повесить на кнопку то работает. Всё правильно считает.
Но если изменить код моей программы...
с <<For count2:=1 to 8 do>> на
<<For count2:=1 to 4 do>> то нет!!!
← →
default © (2004-06-13 20:39) [8]опять же [6]
что должно получиться?
а какая разница между этим
for count:=Low(RecArray.ArrayPoint) to High(RecArray.ArrayPoint) do
begin
For count2:=1 to 4 do
begin
localpoint.X := RecArray.ArrayPoint[count].X + Courses[count2].X;
localpoint.Y := RecArray.ArrayPoint[count].Y + Courses[count2].Y;
end;
end;
и этим
localpoint.X := RecArray.ArrayPoint[High(RecArray.ArrayPoint) ].X + Courses[4].X;
localpoint.Y := RecArray.ArrayPoint[High(RecArray.ArrayPoint) ].Y + Courses[4].Y;
?
смысл цикла?
← →
AAAlexeyAAA (2004-06-13 20:42) [9]есть массив точек...[x,y]
мне нужно помотреть окружающие их точки на предмет нахождения в них 0 или 1
← →
AAAlexeyAAA (2004-06-13 20:44) [10]procedure TForm1.StartGo(EP,SP : TPoint);
var localpoint : TPoint; // вспомогательная переменная, для сокращ. записи
count2,count : integer;
SchetRast, addcount : integer;
begin
If (EP.X = SP.X) and (EP.Y = SP.Y) then
begin
ShowMessage("Начальная и конечная точки совпадают");
Exit;
end;
SetLength(RecArray.ArrayPoint,1);
SetLength(RecArray.Rastoyanie,1);
RecArray.ArrayPoint[0].X := SP.X;
RecArray.ArrayPoint[0].Y := SP.Y;
RecArray.Rastoyanie[0] := Distantion(SP);
SchetRast := Distantion(SP);
while Length(RecArray.ArrayPoint)<>0 do
begin
While Proverka(SchetRast)=true do
begin
for count:=Low(RecArray.ArrayPoint) to High RecArray.ArrayPoint) do
begin
If RecArray.Rastoyanie[count] = SchetRast then
begin
For count2:=1 to 8 do
begin
If MapArray[RecArray.ArrayPoint[count].X + Courses[count2].X,
RecArray.ArrayPoint[count].Y + Courses[count2].Y] = 0 then // если клетка равна 0
begin
localpoint.X := RecArray.ArrayPoint[count].X + Courses[count2].X;
localpoint.Y:= RecArray.ArrayPoint[count].Y + Courses[count2].Y;
If (localpoint.X = EP.X) and (localpoint.Y = EP.Y) then
begin
ShowMessage("NAydeno!!!");
break;
Exit;
end; {end If (localpoint.X = EP.X) and (localpoint.Y = EP.Y)}
{увелич массив на 1 элемент и записываем координаты точки и расстояние: от SP до EP через текущую точку}
SetLength(RecArray.ArrayPoint, Length(RecArray.ArrayPoint)+1);
RecArray.ArrayPoint[High(RecArray.ArrayPoint)].X := localpoint.X;
RecArray.ArrayPoint[High(RecArray.ArrayPoint)].Y := localpoint.Y;
SetLength(RecArray.Rastoyanie, Length(RecArray.Rastoyanie)+1);
RecArray.Rastoyanie[High(RecArray.Rastoyanie)] := Distantion(localpoint);
{изменяем 0 поля(карты) на расстояние: от SP до EP через текущую точку}
MapArray[localpoint.X, localpoint.X] := Distantion(localpoint);
end;{ End IF MapArray[RecArray.ArrayPoint[count].X + Courses[count2].X,RecArray.ArrayPoint[count].Y + Courses[count2].Y] = 0 }
end; { End For count2:=1 to 8 do}
end;{ End If RecArray.Rastoyanie[count] =SchetRast}
Inc(SchetRast);
move(RecArray.ArrayPoint[count+1], RecArray.ArrayPoint[count], ((High(RecArray.ArrayPoint)-count)*SizeOf(RecArray.ArrayPoint)));
end;{ End for count:=Low(RecArray.ArrayPoint) to High(RecArray.ArrayPoint)}
{ удаляем "отработанный" элемент массива}
end;//While Proverka(SchetRast)=true do
end; { End while Length(RecArray.ArrayPoint)<>0 }
ShowMessage("NE NAydeno!!!");
end;
← →
Gero © (2004-06-13 20:45) [11]
> AAAlexeyAAA (13.06.04 20:44
"О Боже мой! Стали мы совсем чужие..." (c) из песни
← →
AAAlexeyAAA (2004-06-13 20:46) [12]может я закину весь проект...тебе на мыло...глянешь?
← →
default © (2004-06-13 20:50) [13]нееее!
вроде явных "промахов" не видно, так что смотри внимательней свой код
проверь один небольшой кусок кода, потом другой и тд. пока не найдёшь ошибку
← →
AAAlexeyAAA (2004-06-13 20:57) [14]Почему на брейкпоинте каждое слагаемое равно 1, а сумма их равна 1, а не 2?
← →
Piter © (2004-06-13 22:28) [15]AAAlexeyAAA (13.06.04 20:57) [14]
у тебя исходники под D7? Заархивируй их (без exe файла) и кинь мне на piter007@newmail.ru
И скажи на какой строчке ошибка, то есть где ставить брекпоинт, чтобы аргументы были по 1, а сумма тоже 1
Мне очень интересно
← →
Piter © (2004-06-14 14:32) [16]AAAlexeyAAA (13.06.04 20:57) [14]
очень интересный случай! Видимо, ошибка в оптимизаторе Дельфовом...
Пока копаю дальше...
← →
default © (2004-06-14 16:07) [17]AAAlexeyAAA скинь на ___ALex___@inbox.ru
Piter © (14.06.04 14:32) [16]
вряд-ли...
← →
Piter © (2004-06-14 16:24) [18]AAAlexeyAAA (13.06.04 20:57) [14]
в общем, рассказываю. Конечно, компилятор не ошибся и оптимизация не ошибочна, но некие грабли здесь есть (для новичка, я думаю, очень страшные грабли).
У тебя есть циклFor count2:=1 to 8 do
begin
If MapArray[RecArray.ArrayPoint[count].X + Courses[count2].X,
RecArray.ArrayPoint[count].Y + Courses[count2].Y] = 0 then // если клетка равна 0
begin
localpoint.X := RecArray.ArrayPoint[count].X + Courses[count2].X;
localpoint.Y := RecArray.ArrayPoint[count].Y + Courses[count2].Y;
...
Как должен выполняться данный цикл? Переменной Count2 присваивается значение 1, выполняется тело цикла. Потом Count2 присваивается 2 и опять выполняется тело цикла. И так до 8 или пока не прервешь цикл оператором Break.
И так оно и есть на самом деле, если ты отключишь оптимизацию "Project -> Options" (или SHIFT+CTRL+F11). Потом вкладка "Compiler" и галочка "Optimization". (после переключения галочки не забудь пересобрать проект, нажав "Project -> Build FindPath")
Но при включенной оптимизации цикл программно выполняется не так! Сначала Count2 присваивается значение 8 и выполняется тело цикла, потом 7, 6 и так до 1. То есть, цикл идет в обратную сторону. Но при этом, если идет обращение к счетчику Count2 внутри цикла, то подставляется "правильное" значение, как если бы цикл шел от 1 до 8.
Давай на примере. Допустим, при ВКЛЮЧЕННОЙ оптимизации значение счетчика Count2 = 6 (это как раз то значение, при котором первый раз будет выполнен if )
Как будет выполняться строка:localpoint.X := RecArray.ArrayPoint[count].X + Courses[count2].X;
?
вовсе не так как ты думаешь! Да, Count2 равен 6. Но ведь включена оптимизация, и на самом деле в строчку будет вместо count2 подставлено число 3 (когда Count2 будет равен 5, то будет подставлено 4 и т.д.).
А проблема в том, что IDE Delphi этого не понимает. Программно все правильно, на третьей итерации тело цикла будет выполнено так, как будто значение счетчика равно 3 (хотя на самом деле Count2 = 6). При этомlocalpoint.X
присвоится значение, равное RecArray.ArrayPoint[count].X (а это 1) плюс Courses[3].X (а это тоже 1). В результате получим 2 и все правильно!
Но если по брекпоинту смотреть на значение Courses[count2].X - то IDE покажет значение "-1", так как будет смотреть шестой элемент массива. Понимаешь? Компилятор знает, что он пустил цикл наоборот, от 8 до 1 и учитывает это при выполнении цикла. А IDE Delphi не учитывает, он видит, что Count2 равен 6, ну и показывает шестой элемент, он не знает, что идет только третья итерация.
Вот и получаются глюки. Если ты в WatchList занесешь выражениеRecArray.ArrayPoint[count].Y + Courses[count2].Y
то оно в WatchList будет равно нулю! А на самом деле компилятор в данной строчке посчитает его как 2! Вот такие забавности есть в Дельфи.
Во всем написанном ты можешь сам убедиться, поигравшись с флажком оптимизации (после переключения галочки не забудь пересобрать проект, нажав "Project -> Build FindPath").
Выход из данной ситуации - отлаживать приложение с выключенной оптимизацией, тогда никаких разногласий между IDE Delphi и компилятором не будет. А когда программа будет готова, то перед финальной сборкой включить оптимизацию (это повышает скорость выполнения программы и уменьшает ее объем).
← →
Piter © (2004-06-14 16:32) [19]И еще замечания по программе:
нафига ты объявляешь:type TPoint = record
X : longint;
Y : longint;
end;
Тип TPoint и так уже объявлен в модуле Windows, который у тебя подключен
← →
AAAlexeyAAA (2004-06-14 22:43) [20]Piter
Большое спасибо за помощь! Я догадывался, что дело в компиляторе,..точнее думал, что чего-то в директивах компилятора нужно делать...(добавлять+/удалять-).
Об том, что счётчик идёт наоборот я видел. Просто по сравнению с вопиющем 1+1=1, я на это закрыл глаза. (да и мне большой разницы то нет,...в каком порядке оно поедет: туда или обратно)
Но есть одно НО, к-рого я так и не понял!
1-ое: Далее по коду есть такая строка(от проблемной строки на 15 вниз, включая комементарии). Она ну никак не влияет на шаги циклов...где всё смешалось, мечи секиры, топоры....
Так вот, я немного ошибся, вместо:
MapArray[localpoint.X, localpoint.X] := Distantion(localpoint);
нужно записать
MapArray[localpoint.X, localpoint.Y] := Distantion(localpoint);
1. Вопрос первый. Почему после изменения ЭТОЙ строки. Всё работает без отключения оптимизации. (так я поборол проблему сложений 1+1)...:)
← →
Piter © (2004-06-15 15:13) [21]AAAlexeyAAA (14.06.04 22:43) [20]
Вопрос первый. Почему после изменения ЭТОЙ строки. Всё работает без отключения оптимизации
ты не прав. Изменение данной строки ничего не меняет. Но немного применив свои телепатические способности вот что хочу сказать. ТЫ УЧЕЛ МОИ ПРИМЕЧАНИЯ В СКОБОЧКАХ?
после переключения галочки оптимизации не забудь пересобрать проект, нажав "Project -> Build FindPath")
Ты это сделал? Наверняка, ты поставил галочку оптимизации и запустил тут же приложение (F9) - и ничего не изменилось. Программа запустилась такая же неоптимизированная. Чтобы изменения вступили в силу - надо сделать Build.
Не дай бог выяснится, что дело в этом. Потому что обидно - пишешь, пишешь примечания. А их все равно не читают... ты бы постарался вникнуть в каждое слово, написанное мной в предыдущем посте. Пусть у тебя уйдет час на это. Пусть день, зато поймешь. А ты небось по диагонали почитал, понял, что просто надо вырубить оптимизацию и успокоился....
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.06.27;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.047 c