Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.02.2011, 11:18   #1
Elvisnya
Пользователь
 
Аватар для Elvisnya
 
Регистрация: 13.09.2008
Сообщений: 24
Вопрос Счетчик цикла в отладчике

Всем добрый день. Столкнулся со следующей проблемой. Если добавить переменную i в WatchList (Ctrl+F5), то в этом WatchList'е в первом случае (коде) она будет изменяться в следующей последовательности 0,1,2,3,4,5,6. Вроде бы всё ОК. Но во втором коде переменная i будет изменяться так: 6,5,4,3,2,1 - фигня какая то! У меня цикл идёт на увеличение, а переменная уменьшается . Может кто знает почему такое происходит? Turbo Delphi 2006
Код:
procedure TForm1.ButtonTestClick(Sender: TObject);
var
  i:integer;
begin
  for i:= 0 to 5 do
    ListBox1.Items.Append(IntToStr(i));
end;
Код:
procedure TForm1.ButtonTestClick(Sender: TObject);
var
  i:integer;
begin
  for i:= 0 to 5 do
    ListBox1.Items.Append('Текст');
end;
Elvisnya вне форума Ответить с цитированием
Старый 19.02.2011, 11:35   #2
Elvisnya
Пользователь
 
Аватар для Elvisnya
 
Регистрация: 13.09.2008
Сообщений: 24
По умолчанию

Нашёл. Оказывается что бы счётчик в циклах
Код:
for to do
всегда считал от меньшего к большему (например от 0 к 10) нужно ставить
Код:
{$O-}
В это место
Код:
implementation

{$R *.dfm}

{$O-}
Что это за команда и почему происходит "баг" из верхнего поста читать ниже:
http://www.cyberforum.ru/delphi-begi...ead169152.html
Elvisnya вне форума Ответить с цитированием
Старый 19.02.2011, 11:47   #3
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,543
По умолчанию

{$O-}
отключение оптимизатоа кода.

Компьютеру удобнее если цикл выполняется сверху вниз (9,8,7,6,...,0). Поэтому если внутреннему коду без разницы в каком порядке выполнять (второй пример не зависит от i) то он меняет порядок на более оптимальный (по его мнению).
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 19.02.2011 в 11:51.
evg_m вне форума Ответить с цитированием
Старый 19.02.2011, 14:04   #4
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

не по ее мнению. а она также оптимизирует тело цикла. на ассемблере это все видно. если надо то часа через два могу показать пример.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 25.02.2011, 23:57   #5
chertovich
Форумчанин
 
Аватар для chertovich
 
Регистрация: 26.07.2009
Сообщений: 489
По умолчанию

Цитата:
Сообщение от evg_m Посмотреть сообщение
{$O-}
отключение оптимизатоа кода.

Компьютеру удобнее если цикл выполняется сверху вниз (9,8,7,6,...,0). Поэтому если внутреннему коду без разницы в каком порядке выполнять (второй пример не зависит от i) то он меняет порядок на более оптимальный (по его мнению).
Не компьютеру удобно, а удобно ассемблировать в команду LOOP ассемблера
Если в глубине души вы программист, то, следуя своим наклонностям, вы захотите написать кусок кода.
chertovich вне форума Ответить с цитированием
Старый 26.02.2011, 09:53   #6
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

Более того, если вы напишите
Код:
  for i:= 5 to 10 do
    ListBox1.Items.Append('Текст');
всеравно, i будет меняться от 6 до 1. Компилятор в Delphi тем и славиться, что производит хорошую оптимизацию кода (ну, обычно, по крайней мере если код не совсем говнокод с отсутствием логики).
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
  i, j, k: Integer;
  b, e: Cardinal;
begin
  b := GetTickCount;
  for i := 1 to 100000000 do
    for j := 6 downto 1 do
      k := 0;
  e := GetTickCount;
  if k = 0 then
    ShowMessage (IntToStr(e-b));
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  i, j, k: Integer;
  b, e: Cardinal;
begin
  b := GetTickCount;
  for i := 1 to 100000000 do
    for j := 5 to 10 do
      k := 0;
  e := GetTickCount;
  if k = 0 then
    ShowMessage (IntToStr(e-b));
end;

{$O-}
procedure TForm1.Button3Click(Sender: TObject);
var
  i, j, k: Integer;
  b, e: Cardinal;
begin
  b := GetTickCount;
  for i := 1 to 100000000 do
    for j := 0 to 5 do
      k := 0;
  e := GetTickCount;
  ShowMessage (IntToStr(e-b));
end;
{$O+}
Обобщая: Во втором цикле нам без разницы как i перебирать, а компу так (от 6 до 1) будет быстрее. Поэтому лучше не трогать оптимизацию, если не понимаете, как она работает.

P.S.: Хотя нюансы конечно же есть. Вот, немного подкорректировал, и картина уже несколько изменилась:
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
  i, j, k: Integer;
  b, e: Cardinal;
begin
  k := 0;
  b := GetTickCount;
  for i := 1 to 100000000 do
    for j := 6 downto 1 do
      inc (k);
  e := GetTickCount;
  if k > 0 then
    ShowMessage (IntToStr(e-b));
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  i, j, k: Integer;
  b, e: Cardinal;
begin
  k := 0;
  b := GetTickCount;
  for i := 1 to 100000000 do
    for j := 0 to 5 do
      inc (k);
  e := GetTickCount;
  if k > 0 then
    ShowMessage (IntToStr(e-b));
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  i, j, k: Integer;
  b, e: Cardinal;
begin
  k := 0;
  b := GetTickCount;
  for i := 1 to 100000000 do
{$O-}
    for j := 5 to 10 do
      inc (k);
{$O+}
  e := GetTickCount;
  if k > 0 then
    ShowMessage (IntToStr(e-b));
end;

Последний раз редактировалось Sibedir; 26.02.2011 в 10:01.
Sibedir вне форума Ответить с цитированием
Старый 26.02.2011, 13:54   #7
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

Цитата:
Сообщение от chertovich Посмотреть сообщение
Не компьютеру удобно, а удобно ассемблировать в команду LOOP ассемблера
Loop тормозная, так что при оптимизации по скорости любой нормальный компилятор сделает dec ecx + jnz.
Somebody вне форума Ответить с цитированием
Старый 26.02.2011, 15:08   #8
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Somebody, точно так оптимизатор Delphi и делает:

Последний раз редактировалось Serge_Bliznykov; 26.02.2011 в 15:15.
Serge_Bliznykov вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Счетчик. Bilargo JavaScript, Ajax 2 15.08.2010 13:54
Создание программы в системном отладчике Debug McDoC Помощь студентам 2 06.05.2010 13:40
Переход от цикла к циклу не выходя из цикла (без multithreading) Qousio Общие вопросы C/C++ 2 16.05.2009 09:27
Оператор цикла с предусловием While. Оператор цикла с пост условием Repeat McMilin Помощь студентам 7 11.11.2007 14:10