Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Встроенный счётчик есть?


Автор: Rohoss 17.3.2009, 22:25
Есть ли в Delphi какая-то переменная, которую можно использовать вместо счётчика цикла?
Код

var
  I: Integer;
begin
  for I := 0 to List.Count - 1 do
  begin
    ..........................
  end;
end;

В таких случаях можно было бы и не писать var. Может в VCL завалялась какая-то переменная, которую можно использовать для данных целей?

Автор: kami 17.3.2009, 22:46
Цитата(Rohoss @  17.3.2009,  22:25 Найти цитируемый пост)
В таких случаях можно было бы и не писать var.

нельзя. ObjectPascal, как и Delphi - строгие языки, объявлять переменные нужно обязательно, причем тип играет огромное значение. К примеру, следующий цикл будет выполнен великое множество раз, если List.Count=0.

Код

var
  I: DWORD;
begin
  for I := 0 to List.Count - 1 do
  begin
    ..........................
  end;
end;



Цитата(Rohoss @  17.3.2009,  22:25 Найти цитируемый пост)
Может в VCL завалялась какая-то переменная, которую можно использовать для данных целей?

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

Автор: bems 17.3.2009, 22:50
даже если бы где-то в другом модуле и была ненужная переменная, использовать ее не получилось бы. Счетчик цикла должен быть объявлен там же, где и цикл

Автор: Данкинг 17.3.2009, 23:39
 smile А сиё вообще хоть в каком-нибудь языке есть?! smile 

Автор: former 18.3.2009, 00:04
Цитата(bems @  17.3.2009,  22:50 Найти цитируемый пост)
даже если бы где-то в другом модуле и была ненужная переменная, использовать ее не получилось бы. Счетчик цикла должен быть объявлен там же, где и цикл 

Да ну! Ну а если эта переменная глобальная, объявлена в модуле главной формы (программы)?
А из VCL нет.

Автор: kami 18.3.2009, 00:14
Цитата(former @  18.3.2009,  00:04 Найти цитируемый пост)
Да ну!

Ну да.  bems прав. Delphi по этому поводу говорит, что for loop-control variable must be a simple local variable.
А речь идет именно о переменных, объявленных в других модулях (если конкретнее - в исходниках VCL), которые планируется задействовать в своем коде в качестве счетчиков цикла.

Автор: former 18.3.2009, 00:15
Цитата(kami @  18.3.2009,  00:14 Найти цитируемый пост)
loop-control variable must be a simple local variable

это точно. пробовал с Tag.  Ругается. smile 

Автор: Rohoss 18.3.2009, 00:37
Цитата(Данкинг @  17.3.2009,  23:39 Найти цитируемый пост)
А сиё вообще хоть в каком-нибудь языке есть?!

В  С – подобных языках это и не требуется, так как переменная объявляется прямо на месте

Автор: Данкинг 18.3.2009, 00:39
Цитата(Rohoss @  18.3.2009,  00:37 Найти цитируемый пост)
В  С – подобных языках это и не требуется, так как переменная объявляется прямо на месте

Но всё равно же объявление переменной присутствует, пусть и не такое, как в Дельфи ( for (i = 0;.....).

Автор: bems 18.3.2009, 01:14
Цитата(former @  18.3.2009,  00:04 Найти цитируемый пост)
Да ну!
Да да!

Автор: Matematik 18.3.2009, 14:41
В 2009 появилась конструкция for in

Код

procedure TForm1.Buton1Click(Sender: TObject);
var
  s,z : string;
  c : Char;
  sl : TStringList;
begin
  z := '1234';
  for c in z do
    ShowMessage(c);

  sl := TStringList.Create;
  sl.Add('4');
  sl.Add('3');
  sl.Add('2');
  sl.Add('1');

  for s in sl do
    ShowMessage(s);

end;


Автор: THandle 18.3.2009, 14:57
Цитата(Matematik @  18.3.2009,  14:41 Найти цитируемый пост)
В 2009 появилась конструкция for in


Небольшая поправка: цикл for...in...do появился еще в Delphi 2005.

Автор: Gwire 18.3.2009, 15:10
smile есть пару вариантов, если не устраевает обычный.
Да и в зависимости от того какую цель приследовать.
Код
procedure TForm1.Button2Click(Sender: TObject);
  procedure BodyFor(i: Integer);
  begin
      ShowMessage( IntToStr(i) );
  end;
begin
    asm
      push eax           ;// сохраняем значение ebх
      push ecx           ;// сохраняем значение eсх
      mov ecx, 5
      @begin:
          push eax
          push ecx
          mov eax, ecx
          call BodyFor
          pop ecx
          pop eax
          loop @begin  
      @end:
      pop ecx            ;// востонавливаем значение eсх
      pop eax            ;// востонавливаем значение ebх (в обратном порядке)
    end
end;

smile Сложнее чем обычный зато со спецальной управляющей есх
Код
procedure TForm1.Button3Click(Sender: TObject);
var P: Pointer;
begin
    GetMem( P, SizeOf(Integer) );       // управляющая цикла
    Integer(P^):= 5;                    // ^ справа - значение указателя
    while (Integer(P^) <> 0 ) do
    begin
        ShowMessage( IntToStr(Integer(P^)) );
        Dec( Integer(P^) );
    end;
    FreeMem(P);                         // нужно освободить память

    GetMem( P, SizeOf(Integer) );       // строковая переменная
    String(P^):= 'Строка к примеру';
    ShowMessage( String(P^) );
    FreeMem(P);

    GetMem( P, SizeOf(TForm) );         // и даже форма
    TForm(P^):= TForm.Create(nil);
    TForm(P^).ShowModal;
    TForm(P^).Free;
    FreeMem(P);                         // <-- Не завываем освободить
end;

smile Этот вариант избавляет от лишних переменных
Но стоит ли так "ПАРИТЬ" себе голову? По моему этот вид лучше и проще:
Код
procedure TForm1.Button4Click(Sender: TObject);
var I: Integer;
begin
    for I:= 1 to 5 do ShowMessage( IntToStr(I) );
end;


Автор: Beltar 20.3.2009, 12:08
Цитата

А сиё вообще хоть в каком-нибудь языке есть?


В Аде ЕМНИП переменная цикла автоматом становится Integer.

Цитата

В  С – подобных языках это и не требуется, так как переменная объявляется прямо на месте


Если уж заговорили об экономии двух-трех символов, то позволю себе небольшой оффтопик. В Си цикл for, я за таковой вообще не считаю. Т. к. for(i=0;i<n;i++) совершенно аналогично
Код

i:=0;
while i<n do
  begin
  //
  Inc(i);
  end;


В обоих случаях описано ровно 3 операции. Укажите хоть одно отличие от while? На кой фиг это дебильное i++ вообще нужно, если цикл for в 99,9% случаев имеет инкремент 1?

Автор: Dmi3ev 22.3.2009, 13:02
Код

{
    for (int i=0; i<n; i++)
    {
    //...
    }
}

Код

i:=0;
while i<n do
  begin
  //
  Inc(i);
  end;

С++  с Delphi сравнивать?  smile 
Цитата

Укажите хоть одно отличие от while?

1) переменная локальная, вне цикла ее нет, это довольно удобно, даже не собираюсь объяснять чем...
2) начальное значение, условие цикла, а также шаг (все параметры цикла) находятся на одной строке (удобочитабельно)
3) при этом есть возможность запускать цикл вот такого плана
Код

for (int i=0, int j=10; i<j; i++, j--)
{
//...
}

что с while уже будет выглядеть более запутано на мой взгляд...
Цитата

На кой фиг это дебильное i++ вообще нужно

а на кой фиг Inc(i); ?
 (не нравится сделай свою функцию Inc() или пиши i=i+1, кто не дает)
а если серьезно то "++" много возможностей и это удобная штука, а если не умеешь ей пользоваться, то это не значит, что она "дебильная"...
4) 
Цитата

если цикл for в 99,9% случаев имеет инкремент 1

у кого как... 
Код

for (double x=0; x<k; x+=0.2)
{
//...
}

а это чем тебе не цикл?
На самом деле Delphi и С++ сравнивать - глупое занятие, поэтому продолжать не буду...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)