Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 04.09.2011, 19:22
Аватар для Aleks26
Aleks26 Aleks26 вне форума
Прохожий
 
Регистрация: 19.12.2010
Сообщения: 32
Репутация: 12
Вопрос Непонятная работа цикла for

У Фаронова есть простейший пример для иллюстрации работы с массивами. Вроде все просто, но я столкнулся с такой штукой: когда я начинаю цикл for ( он помечен у меня ЦИКЛ2), он считается у меня почему-то в обратном порядке (я пробовал пошагово его пройти и первое значение индекса равно 99, затем 98 и т.д.). Не могу понять, почему он не считает от 2 до N. Подскажите кто-нибудь.

Код:
unit unAverage1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    btnRun: TButton;
    memOutPut: TMemo;
    lblOutPut: TLabel;
    procedure btnRunClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btnRunClick(Sender: TObject);
const
 N = 100;
 Max_Value = 100+1;
var
 m: array[1..N] of Integer;
 i,j: Integer;
 max, min: Integer;
 sum: Real;
 S: String;
begin
 S := '';
 for i := 1 to N do
  begin
   m[i] := Random(Max_Value);
   S := S + #9 + IntToStr(m[i]);
   if i mod 10=0 then
    begin
     memOutPut.Lines.Add(S);
     S := '';
    end
  end;
 sum := m[1];
 max := m[1];
 min := m[1];
 for j := 2 to N do  { ЦИКЛ 2}
  begin
   sum := sum + m[j];
   if m[j] < min then
    min := m[j]
   else if m[j] > max then
    max := m[j]
  end;
 lblOutPut.Caption := ' Минимум = ' + IntToStr(min) + ' Максимум = ' +
                      InttoStr(max) + ' Среднее = ' + FloatToStr(sum/N);
end;

end.
Ответить с цитированием
  #2  
Старый 04.09.2011, 19:49
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
  #3  
Старый 04.09.2011, 20:32
Аватар для Aleks26
Aleks26 Aleks26 вне форума
Прохожий
 
Регистрация: 19.12.2010
Сообщения: 32
Репутация: 12
По умолчанию

Я в таком формате плохо разбираюсь. Поэтому не понял в чем суть.
Ответить с цитированием
  #4  
Старый 04.09.2011, 21:43
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Скорее всего оптимизирующий компилятор перевернул цикл, поскольку в машинном коде цикл от N-1 до 0 несколько проще.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
  #5  
Старый 05.09.2011, 07:00
Vocabulary Vocabulary вне форума
Новичок
 
Регистрация: 17.09.2009
Сообщения: 85
Репутация: 9
По умолчанию

- Дельфийский компилятор не имеет права "переворачивать" цикл, а потому этого никогда и не делает.
- Значение константы N определено как число 100, следовательно начало цикла в обратном порядке не может начинаться с 99.
- Проверка в Delphi именно приведенного кода показала, что значение управляющей переменной цикла (j) начинается с 2 и заканчивается на значении 100.

По этим признакам косвенно можно предположить варианты:
1. Автор лукавит (ошибся) и привел не тот код, в котором у него цикл начинается со значения 99.
2. Компилятор не дельфийский.
3. Полтергейст (сиречь Барабашка) в компиляторе.
Ответить с цитированием
  #6  
Старый 05.09.2011, 07:12
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Замени на while и не парься.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
  #7  
Старый 05.09.2011, 08:31
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

все правильно: цикл иногда "переворачивается". вот же пример:
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
const
  n = 10;
var
  i: Integer;
begin
  for i:=1 to n do
  begin
    Sleep(0);
//    Memo1.Lines.Add(IntToStr(i));
  end;
end;

end.

ставим точку останова на for i:=1 to n do и смотрим Debug CPU при закомментареной строчке Memo1.Lines.Add(IntToStr(i)); и раскомментареной: "цикл будет крутиться в разные стороны "
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #8  
Старый 05.09.2011, 09:11
Аватар для Aleks26
Aleks26 Aleks26 вне форума
Прохожий
 
Регистрация: 19.12.2010
Сообщения: 32
Репутация: 12
По умолчанию

Спасибо за пример. Однако четко сформулировать, когда цикл пойдет в каком направлении, у меня не получается.
Ответить с цитированием
  #9  
Старый 05.09.2011, 09:22
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

Aleks26, не забивай себе этим голову у тебя никогда не возникнет ситуации, что из-за "неправильной" работы цикла твоя программа будет "не правильно" работать.
ЗЫ. хотя если и возникнет, то я буду очень рад такому примеру
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #10  
Старый 05.09.2011, 21:23
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Цитата:
Сообщение от Vocabulary
- Дельфийский компилятор не имеет права "переворачивать" цикл...
Не путайте людей, если не знаете о чём говорите. Дельфи не просто "переворачивает" циклы, а делает это довольно часто. Как уже было сказано для оптимизации кода. А посему срочно учить "матчасть".
Цитата:
Сообщение от NumLock
ЗЫ. хотя если и возникнет, то я буду очень рад такому примеру
Мне кажется, дождаться не получится. Это длится довольно давно (не ясно с какой версии) и ещё никто при этом глюка не словил.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.

Последний раз редактировалось angvelem, 05.09.2011 в 21:27.
Ответить с цитированием
  #11  
Старый 05.09.2011, 23:53
Аватар для Aristarh Dark
Aristarh Dark Aristarh Dark вне форума
Модератор
 
Регистрация: 07.10.2005
Адрес: Москва
Сообщения: 2,907
Версия Delphi: Delphi XE
Репутация: выкл
По умолчанию

Я один раз, правда давно очень, сейчас глянул дату модуля - 2006 год.
вот код который по разному работал с оптимизацией и без нее:
Код:
  for i:=1 to SummArrayPoint do
  	begin
		  Excel.Sheets.Add;
      HouseSheet:=Excel.WorkBooks[1].ActiveSheet;
      HouseSheet.Name:=MainData[SummData[i,21],3]+MainData[SummData[i,21],4];
      ExcelHeader(HouseSheet,AccGroupName,MesN,1);
      HouseSheet.Range['A3:T3']:=TableHeader;
      if i=SummArrayPoint then
      	lenHouseArr:=arrlen-SummData[i,21]
      else
        lenHouseArr:=SummData[i+1,21]-SummData[i,21];
      HouseData:=0;
      HouseData:=VarArrayCreate([1,lenHouseArr,1,20],varVariant);
      for n:=1 to 20 do
      	for m:=1 to lenHouseArr do
        	HouseData[m,n]:=MainData[SummData[i,21]+m-1,n];
		  HouseSheet.Range['A4:T'+Trim(IntToStr(lenHouseArr+3))].Value:=HouseData;
      for n:=1 to 20 do
      	SummHouse[1,n]:=SummData[i,n];
      HouseSheet.Range['A'+Trim(IntToStr(lenHouseArr+4))+':T'+Trim(IntToStr(lenHouseArr+4))]:=SummHouse;
      HouseSheet.Range['A'+Trim(IntToStr(lenHouseArr+4))].Value:='ИТОГО';
      HouseSheet.Range['A'+Trim(IntToStr(lenHouseArr+4))+':F'+Trim(IntToStr(lenHouseArr+4))].Merge;
      HouseSheet.Range['A'+Trim(IntToStr(lenHouseArr+4))+':F'+Trim(IntToStr(lenHouseArr+4))].HorizontalAlignment:=$FFFFEFC8;
      HouseSheet.Range['A'+Trim(IntToStr(lenHouseArr+4))+':F'+Trim(IntToStr(lenHouseArr+4))].VerticalAlignment:=$FFFFEFF4;
      HouseSheet.Range['A'+Trim(IntToStr(lenHouseArr+4))+':T'+Trim(IntToStr(lenHouseArr+4))].Font.Bold:=True;
	  	HouseSheet.Cells.Select;
	  	HouseSheet.Cells.EntireColumn.AutoFit;
  		HouseSheet.Range['A4'].Select;
		  Excel.ActiveWindow.FreezePanes:=True;
//			HouseSheet.PageSetup.PrintTitleRows:='$3:$3';
    end;
__________________
Некоторые программисты настолько ленивы, что сразу пишут рабочий код.

Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты.
Ответить с цитированием
  #12  
Старый 06.09.2011, 08:26
Аватар для Aleks26
Aleks26 Aleks26 вне форума
Прохожий
 
Регистрация: 19.12.2010
Сообщения: 32
Репутация: 12
По умолчанию

Спасибо за консультации. Для меня важно было лишь удостовериться, что это не я что-то не так написал.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 18:45.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025