2013-05-01 3 views
-2

У меня есть «i», которая является целочисленной переменной, и я бы хотел сделать цикл, который увеличивает «i» с 40000 до 90000, добавляя 1000 каждый раз. Каждый результат появится в ComboBox.Приращение целочисленной переменной в цикле

Пример: 40000 - 41000 - 42000 - 43000 - ... - 88000 - 89000 - 90000

Мой код выглядит следующим образом:

var i:integer; 
begin 
for i:= 40000 to 90000 do 
    begin 
    ComboBox1.AddItem(IntToStr(i), nil); //until here the code works 
    Inc(i, 1000);       
    end; 

Есть ли у вас какие-либо предложения?

+1

Хотя я и многие знают природу того, что тип ошибки вы получаете, вы должны * всегда * сообщить нам, что сообщение об ошибке есть. –

+1

Пожалуйста, прочитайте сообщение об ошибке целиком и проконсультируйтесь (F1) с документацией для разрешения. В нем указано, что вы не можете изменить счетчик цикла 'for'. – OnTheFly

ответ

9

Вы не можете изменить переменную цикла for внутри цикла.

Что вы хотите, это:

for i := 0 to 50 do 
    ComboBox1.AddItem(IntToStr(40000 + 1000 * i), nil) 

Но! Это довольно неэффективно. Вы должны рассмотреть

ComboBox1.Items.BeginUpdate; 
for i := 0 to 50 do 
    ComboBox1.Items.Add(IntToStr(40000 + 1000 * i)); 
ComboBox1.Items.EndUpdate; 
+0

Несмотря на то, что это делает эту работу, я думаю, что этот тип цикла скрывает логику для читателя. Обычно я пытаюсь реализовать этот цикл как цикл while, как показано в статье @KenWhite, но на следующем этапе нужно реализовать библиотеку, которая заботится о цикле for.step. См. Мой ответ, второй - хранитель моих утилит. –

+0

@ LURD: Я как раз собирался добавить опцию 'while' к моему ответу, но Кен избил меня. Во всяком случае, я думаю, что это зависит от «базовой» логики. Иногда цикл 'for' может быть наиболее естественным. (Может возникнуть ощущение, что оценка «while» пытается имитировать то, что программист должен действительно доказать во время разработки.) –

9

Альтернативы @ AndreasRejbrand, решение которого является while петли:

i := 40000; 
while i <= 90000 do 
begin 
    ComboBox1.AddItem(IntToStr(i), nil); 
    Inc(i, 1000); 
end; 

или `повторить ':

i := 40000; 
repeat 
    ComboBox1.AddItem(IntToStr(i), nil); 
    Inc(i, 1000); 
until i > 90000; 
+2

+1, но я думаю, что использование '<= 90000' немного путается для некоторых людей. –

+1

@Jerry: Я не предлагал использовать его вместо этого; Я просто предложил альтернативу. Я поддержал ответ Андреаса. :-) –

+0

Я имел в виду, что использовал бы '<= 90000', а не' <90001', что делает то же самое и не обязательно имеет значение, кроме читаемости –

3

Компилятор запрещает изменять переменный цикл.

Существует способ включить поддержку петли for..step. У вас должна быть версия Delphi, поддерживающая дженерики (Delphi-2009 +).

Просто сделать это заявление в полезности единицы:

Type 
    ForLoop = record 
    class procedure Step(Start,Stop,AStep : Integer; 
          ALoop : TProc<Integer>); static; 
    end; 

class procedure ForLoop.Step(Start,Stop,AStep : Integer; ALoop: TProc<Integer>); 
begin 
    while (start <= stop) do 
    begin 
    ALoop(start); 
    Inc(Start,AStep); 
    end; 
end; 

И использовать его как это:

ForLoop.Step(40000,90000,1000, 
    procedure (i : Integer) 
    begin 
    ComboBox1.AddItem(IntToStr(i), nil); 
    end 
); 

В Delphi 2005, были добавлены методы по записи плюс перечисление for in.

Зная это, можно реализовать другой цикл цикла с функциональностью шага.

type 
    Range = record 
    private 
    FCurrent,FStop,FStep : Integer; 
    public 
    constructor Step(Start,Stop,AnIncrement : Integer); 
    function GetCurrent : integer; inline; 
    function MoveNext : boolean; inline; 
    function GetEnumerator : Range; // Return Self as enumerator 
    property Current : integer read GetCurrent; 
    end; 

function Range.GetCurrent: integer; 
begin 
    Result := FCurrent; 
end; 

function Range.GetEnumerator: Range; 
begin 
    Result := Self; 
end; 

function Range.MoveNext: boolean; 
begin 
    Inc(FCurrent,FStep); 
    Result := (FCurrent <= FStop); 
end; 

constructor Range.Step(Start,Stop,AnIncrement: Integer); 
begin 
    Self.FCurrent := Start-AnIncrement; 
    Self.FStop := Stop; 
    Self.FStep := AnIncrement; 
end; 

И теперь вы можете написать:

for i in Range.Step(40000,90000,1000) do 
    ComboBox1.AddItem(IntToStr(i), nil); 

Копать во внутренние работы этого примера, см more-fun-with-enumerators.


Легко реализовать версию двух примеров .StepReverse выше, и я оставлю это в качестве упражнения для заинтересованного читателя.

0

Мы также можем сделать петлю от 40 до 90 и умножить показатель с 1000

var i: integer; 
begin 
    for i:= 40 to 90 do 
    begin 
     ComboBox1.AddItem(IntToStr(i*1000), nil);  
    end;     
end; 
Смежные вопросы