BDL3 0 / 0 / 0 Регистрация: 28.12.2010 Сообщений: 36 |
||||
1 |
||||
26.05.2012, 12:29. Показов 38311. Ответов 4 Метки нет (Все метки)
Задача: Дан массив случайных чисел. Нужно найти макс. и мин. элемент и поменять их местами. Так вот, в этом фрагменте программы:
а именно в строке for i:= 0 to (n-1) do выдает ошибку: [DCC Error] Unit1.pas(47): E2081 Assignment to FOR-Loop variable ‘i’
__________________
0 |
3942 / 1867 / 337 Регистрация: 16.03.2012 Сообщений: 3,880 |
|
26.05.2012, 13:10 |
2 |
Именно в этом фрагменте всё нормально. Покажи, как ты описываешь переменную i. И немного больше кода впереди. Может быть цикл в цикле, и во внешнем цикле тоже эта переменная используется.
1 |
2832 / 1641 / 254 Регистрация: 03.12.2007 Сообщений: 4,222 |
|
26.05.2012, 13:11 |
3 |
Наверное, этот цикл внутри другого цикла, в котором переменная — тоже i. Если так, используй другую.
1 |
BDL3 0 / 0 / 0 Регистрация: 28.12.2010 Сообщений: 36 |
||||||||
26.05.2012, 17:49 [ТС] |
4 |
|||||||
Именно в этом фрагменте всё нормально. Покажи, как ты описываешь переменную i. И немного больше кода впереди. Может быть цикл в цикле, и во внешнем цикле тоже эта переменная используется. вот, смотри, побольше захватил:
Добавлено через 2 минуты
0 |
Одиночка 3942 / 1867 / 337 Регистрация: 16.03.2012 Сообщений: 3,880 |
||||||||
26.05.2012, 18:04 |
5 |
|||||||
Ну конечно в одном цикле используешь переменную i и во внутреннем тоже. Используй во внутреннем цикле другую переменную:
Хотя не зная логики работы, не скажешь, как именно нужно делать. Добавлено через 1 минуту Добавлено через 12 минут
1 |
IT_Exp Эксперт 87844 / 49110 / 22898 Регистрация: 17.06.2006 Сообщений: 92,604 |
26.05.2012, 18:04 |
Помогаю со студенческими работами здесь
Ошибка: «For loop control variable must be simple local variable» interface uses Ошибка: «for loop control variable must be simple local variable» procedure TForm1.Button3Click(Sender:… Ошибка «For loop control variable must be simple local variable»
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: 5 |
Модератор: Модераторы
Ошибка в цикле FOR
- Код: Выделить всё
for i:=0 to 10 do
if <условие> then
begin
i:=-1;
break
end;
Получаю:
Error: Illegal assignment to for-loop variable «i»
Согласен на предупреждение, но никак не на ошибку!
Добавлено спустя 3 минуты 48 секунд:
Хотя в Delphi тоже ошибку выдаёт.
- SAK
- постоялец
- Сообщения: 158
- Зарегистрирован: 18.02.2006 00:45:14
- Откуда: Тим
-
- Профиль
- Сайт
Re: Ошибка в цикле FOR
Logo » 02.12.2009 19:03:46
Вы предлагаете изменить синтаксис?
- Logo
- постоялец
- Сообщения: 464
- Зарегистрирован: 20.08.2008 01:00:47
Re: Ошибка в цикле FOR
SAK » 02.12.2009 19:20:12
Да нет, я ничего не предлагаю. Я полностью согласен, что любое присвоение переменной цикла внутри цикла является ошибкой, за исключением случая когда сразу после присвоения цикл принудительно прерывается. Но это никак не относится к синтаксису языка. Просто меня возмутило, что компилятор не позволил сделать операцию не являющуюся ошибочной, вот я на него и обиделся
- SAK
- постоялец
- Сообщения: 158
- Зарегистрирован: 18.02.2006 00:45:14
- Откуда: Тим
-
- Профиль
- Сайт
Re: Ошибка в цикле FOR
скалогрыз » 02.12.2009 20:30:50
это истой воды ошибка, иначе цикл for пришлось бы реализовывать как while — каждый раз проверяя значение счётчика и о граничителя. Что то вроде: while i<=10 do
а for вычисляет количество итераций только один раз, что ОЧЕНЬ существенно для подобных циклов
- Код: Выделить всё
for i:=0 to List.Count - 1 do
List.Add( ... ); // List.Count изменился
в цикел с while это реализуется вот так:
- Код: Выделить всё
cnt:=List.Count;
while i<cnt do ...
———
значение счётчика цикла for изменять можно, НО только для {$mode tp}
- скалогрыз
- долгожитель
- Сообщения: 1801
- Зарегистрирован: 03.09.2008 02:36:48
Вернуться в Free Pascal Compiler
Кто сейчас на конференции
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4
Topic: Strange: Error: Illegal assignment to for-loop variable «i» (Read 43802 times)
I have the following code:
procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
begin
for i:=0 to 100 do
begin
if i=5 then i:=10;
end;
end;
When I try to run it I get Error: Illegal assignment to for-loop variable «i»
Is this a bug in Lazarus or I am doing something wrong?
Logged
Лазар 2,2,4 32 bit; FPC3,2,2; rev: Lazarus_2_2_4 on W10 64bit.
I think you’re not supposed to change the counter/control variable in a for loop — i in this case.
If you need to, try one of the alternatives (a while or until loop — don’t know by heart if you are allowed to change the control variable there)… or just test for i=5,6,7,8 and 9 and skip processing to the next iteration of the loop if necessary.
Logged
For loop is supposed to be a fixed iteration, the termination should be predictable. If you’re used to Turbo Pascal, AFAIK they violate this so it’s allowed. In Turbo Pascal compatibility mode (and perhaps Delphi mode as well), the restriction is removed so it’s allowed as in Turbo Pascal.
Logged
How am I to switch to Turbo Pascal compatibility mode?
I tried with adding -Mtp in Project/Project Options/Linking/Options (-k):/
I checked the checkbox Pass options to linker, too.
I tried to run the code, but I got the same error?
I then uncommented a line # -Mtp in fpc.cfg and I still get the same.
Uncommenting # Mdelphi gave no result, too.
« Last Edit: July 09, 2012, 10:48:39 am by paskal »
Logged
Лазар 2,2,4 32 bit; FPC3,2,2; rev: Lazarus_2_2_4 on W10 64bit.
You’ve done it right, but if the source file contains:
{$mode objfpc}
Then it would be preferred over the -Mtp as explained here. Just remove that from the source file, note that if you’re on Turbo Pascal compatibility mode, you’re coding as in Turbo Pascal. i.e. no classes, no overloading, and many other modern Pascal features (read the docs). A better solution is to change your code not to use for loop because as I said earlier, it’s a violation against the semantic of for loop.
Logged
I have the following code:
procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
begin
for i:=0 to 100 do
begin
if i=5 then i:=10;
end;
end;
When I try to run it I get Error: Illegal assignment to for-loop variable «i»
Is this a bug in Lazarus or I am doing something wrong?
Paskal,
Seems like in your code, nothing gets done when i is from 5 to 9. So you could put code to that effect (do nothing when i is any of 5 to 9).
But correct me if that’s not what you want to happen.
Logged
To add to what leldumbo wrote — any {$mode …} directive in your source will override commandline directives. So to force Turbo Pascal mode you would have to use
{$MODE TP}
Logged
Logged
All posts based on: Win10 (Win64); Lazarus 2.0.10 ‘stable’ (x64) unless specified otherwise…
I tried with {$MODE Delphi} but there is no change. Using TP mode makes no sense, IMHO DOS is dead.
I am fully aware, that I can add an extra counter or use another type of loop, and yet I see no reason for this limitation, so I wonder if it is not a bug.
Does anyone have an idea if there is such a limitation in Delphi?
Elmug, my idea is to remove repeating values for an array/ string grid, etc, I just gave a simpler example.
« Last Edit: July 09, 2012, 01:31:17 pm by paskal »
Logged
Лазар 2,2,4 32 bit; FPC3,2,2; rev: Lazarus_2_2_4 on W10 64bit.
I tried with {$MODE Delphi} but there is no change. Using TP mode makes no sense, IMHO DOS is dead.
I am fully aware, that I can add an extra counter or use another type of loop, and yet I see no reason for this limitation, so I wonder if it is not a bug.
Does anyone have an idea if there is such a limitation in Delphi?Elmug, my idea is to remove repeating values for an array/ string grid, etc, I just gave a simpler example.
Hi Paskal,
Just the thought that changing to downwards compatibility might affect something else, would lead me to rather use code as eny suggests, in which you create your own counter, that you can control.
Surely there must be a reason for the way it is now, otherwise, why would they go to the extra work of not using what was there already, wouldn’t you say?
But maybe there isn’t.
I hope all resolves well there.
Logged
I am fully aware, that I can add an extra counter or use another type of loop, and yet I see no reason for this limitation, so I wonder if it is not a bug.
There is a reason why FP is called a 3GL or HLL: it is easier to develop programs that are easy(ier) to read and understand.
A for control structure is used to execute a statement a fixed number of times (i.e. from a start value to an end value).
This is by design, not a limitation or bug as you call it: http://www.freepascal.org/docs-html/ref/refsu49.html#x141-15100013.2.4
The while and repeat/until give the flexibility for the level of control you seek.
« Last Edit: July 09, 2012, 02:01:12 pm by eny »
Logged
All posts based on: Win10 (Win64); Lazarus 2.0.10 ‘stable’ (x64) unless specified otherwise…
As an addition to what eny said: a fixed iteration loop has a chance to be optimized more than any other loop. For instance: loop unrolling. It relies on the fact that the iteration is fixed (even more, the number of iteration must be constant, instead of just predictable). If you read up compiler optimizations article at wikipedia, you’ll see that a lot of optimizations can be applied to such for-loop.
Logged
Does anyone have an idea if there is such a limitation in Delphi?
Delphi 2007 & XE2 — [DCC Error] Project4.dpr(14): E2081 Assignment to FOR-Loop variable ‘i’
Logged
If you are trying to skip 5 through 10, try this code:
Procedure Tform1.Button1click(Sender: Tobject);
var
I: Integer;
Begin
for I:= 0 to 100 do begin
if (I>4)and(I<11) then
{Do nothing}
else begin
{Add your code here to do what you need}
End;
End;
End;
« Last Edit: July 09, 2012, 03:23:48 pm by Avishai »
Logged
Lazarus Trunk / fpc 2.6.2 / Win32
Or you could do something like:
Procedure Tform1.Button2click(Sender: Tobject);
var
I: Integer;
Begin
I:= 0;
repeat
case I of
0..4, 11..100: begin
ListBox1.Items.Add(IntToStr(I)); //whatever your code should be
End;
End;
inc(I);
Until I>100;
End;
Logged
Lazarus Trunk / fpc 2.6.2 / Win32
We cannot change the value of the indexer variable in a For-In loop.
For demonstration, copy this code into a new Project of type Simple Program, and compile it. Then, add the ‘$’ character to the «Define symDemo» comment in the first line, to convert it to a compiler directive, and try to compile.
For discussion see https://forum.lazarus.freepascal.org/index.php?topic=17488.0
program ForIn; {$AppType Console} { Define symDemo}
var
strChrLst , // list of characters, without separators
idxChrOne : string ; // only one character; indexer in For-In loop
strChrUpr : string = ''; // uppercase version of the current character, init-ed to empty
begin
strChrLst := 'a[z' ; // initialize list of characters to work on
for idxChrOne in strChrLst do begin ; // scan all characters in the list
{$IfNDef symDemo} ; // when "symDemo" is not defined
strChrUpr := UpCase( idxChrOne ) ; // convert the current character to upcase
{$Else} ; // when "symDemo" is defined
idxChrOne := UpCase( idxChrOne ) ; // gives Error 3208 on "idxChrOne"
{$EndIf} ; // done with "symDemo"
if ( strChrUpr < 'A' ) // when the current character is
Or ( strChrUpr > 'Z' ) then begin ; // outside the range of alphabet letters
writeln(StdErr,'Not a letter: ',idxChrOne); // emit the non-letter character on StdErr
end ; // done with the non-letter character
end ; // done scanning characters in the list
end.
|
|
|
Пожалуйста, выделяйте текст программы тегом [сode=pas] … [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как «свернуть» программу в трей.
3. Как «скрыться» от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
… (продолжение следует) …
Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.
Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка — 60 дней. Последующие попытки бан.
Мат в разделе — бан на три месяца…
Ошибка Assignment to FOR-Loop variable
, Помогите понять
- Подписаться на тему
- Сообщить другу
- Скачать/распечатать тему
|
|
Newbie Рейтинг (т): 0 |
Function String_z(filepath: string): string; var fl:file of Byte; byte_z:Byte; str_z:string; i: integer; char_z:char; begin AssignFile(fl, filepath); Reset(fl); for i:=1 to FileSize(fl) do begin //12 Read(fl, byte_z); if byte_z = 35 then begin //5 for i:=i to FileSize(fl) do begin //15 Read(fl, byte_z); if byte_z = 13 then begin // break; end; // end; //15 end //5 else begin //1 if (byte_z >= 48) and (byte_z <= 57) then end; //1 end; //12 CloseFile(fl); end; Перешел из си, не понимаю почему на for i:=i to FileSize(fl) do выдается ошибка [Ошибка] Unit1.pas(54): Assignment to FOR-Loop variable ‘i’
Инициализация же в for проходит один раз, и больше нет присвоение. = С уважением dasV |
jack128 |
|
Moderator Рейтинг (т): 181 |
for i:=1 to FileSize(fl) do // ПЕРВОЕ ПРИСВОЕНИЕ begin //12 Read(fl, byte_z); if byte_z = 35 then begin //5 for i:=i to FileSize(fl) do // ВТОРОЕ ПРИСВОЕНИЕ begin //15 Read(fl, byte_z); if byte_z = 13 then begin // break; end; // end; //15 end //5 else begin //1 if (byte_z >= 48) and (byte_z <= 57) then end; //1 end; //12 |
das |
|
Newbie Рейтинг (т): 0 |
Хорошо, раз так, давай те сделаем так i,j : integer; Поменяем for j:=i to FileSize(fl) do begin //15 После в if добавим if byte_z = 13 then begin // i:=j; break; end; // Толку ноль. С уважением das |
jack128 |
|
Moderator Рейтинг (т): 181 |
das ну и?? Тебя ясно сказали, что НЕЛЬЗЯ внутри цикла for изменять счетчик цикла. НЕЛЬЗЯ. и хоть удавись, но никак ты это правило не обойдешь. Перепиши код, используя цикл while |
das |
|
Newbie Рейтинг (т): 0 |
Спасибо, просто интересно, все же интересно когда все своими руками делаешь. while FileSize(fl) <> 0 do begin //15 Read(fl, byte_z); if byte_z = 13 then begin // break; end; // end; //15 И переписывать то не много, но почему нельзя в нутрии цикла ..не знаю = С уважением das |
bold |
|
Full Member Рейтинг (т): 2 |
i:= j; // А зачем ??? ……… for i:=1 to FileSize(fl) do begin Read(fl, byte_z); if byte_z = 35 then begin for j:=i to FileSize(fl) do begin // j:= i !!! Так вроде логичнее. Read(fl, byte_z); if byte_z = 13 then begin break; // А здесь в первом примере больше ничего небыло. end; end; end; end else begin ………… В одном цикле i внутрии него цикл с j Добавлено 25.09.05, 18:49 |
das |
|
Newbie Рейтинг (т): 0 |
2_bold я просто хотел синхронизировать i и j после выхода из второго цикла. С уважением das Сообщение отредактировано: das — 25.09.05, 19:24 |
tIce |
|
Full Member Рейтинг (т): 17 |
Цитата jack128 @ 25.09.05, 18:35 Тебя ясно сказали, что НЕЛЬЗЯ внутри цикла for изменять счетчик цикла. НЕЛЬЗЯ. и хоть удавись, но никак ты это правило не обойдешь. Простите уважаемый модератор, но: procedure TForm1.Button1Click(Sender: TObject); var i,i_tmp:integer; begin for i:=0 to 100 do begin // showmessage(inttostr(i)); — так… для контроля //копируем i в i_tmp i_tmp:=i; // делаем с i_tmp все что угодно … // inc(i_tmp); … // устанавливаем значение i равным i_tmp copymemory(@i,@i_tmp,2); end; end;
ничего не мешает сделать из этого процедуру и валяй это i как хочешь. Добавлено 26.09.05, 06:22 i:=i_tmp действительно не покатит. низяяяя…. |
Digimaster |
|
tIce IMHO опасная затея. Не зря же это запрещено. |
tIce |
|
Full Member Рейтинг (т): 17 |
извините меня Digimaster, но раз переменная объявлена, значит под нее выделена память (стек и регистры тут сами по себе). Даже если мы превысим значание окончания цикла он просто завершится и все. Долго такой метод юзаю, никаких багов не наблюдал. А то что это запрещено, думаю что Борландовцам было впадлу сделать циклы как в С (скорее всего они придурживались правил начального Паскаля (Досовских версий) и менять ничего не стали), и вообще циклы в делфях очень неудобно реализованы, в отличии от С. |
jack128 |
|
Moderator Рейтинг (т): 181 |
Цитата tIce @ 26.09.05, 06:48 значит под нее выделена память
сие не есть верно. Существует такая фишка как оптимизация. Переменая храниться в памяти, только если её не выкинул отпимизатотр и если к этой переменной была применена операция ‘@’ Сообщение отредактировано: jack128 — 26.09.05, 08:29 |
tIce |
|
Full Member Рейтинг (т): 17 |
Цитата jack128 @ 26.09.05, 08:26 сие не есть верно. Существует такая фишка оптимизация.
да да да, неправ. |
0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
0 пользователей:
- Предыдущая тема
- Delphi: Общие вопросы
- Следующая тема
[ Script execution time: 0,0628 ] [ 16 queries used ] [ Generated: 9.02.23, 13:56 GMT ]
Create an account to follow your favorite communities and start taking part in conversations.
r/pascal
i’m not english native so it’s hard to learn programming. i’m completely new at pascal
var
x:integer;
begin
for x:=2 to 100 do
begin
writeln(x);
x:=x+2;
end;
it was a school assignment, i’m trying to display even number from 1-100 with for loop, but when i run it, it said «Error: Illegal assignment to for-loop variable «x», help me
level 1
// print the first 50 even numbers
for x := 1 to 50 do begin
writeln(x*2);
end;
--------------------------------------
// print only even numbers
for x := 1 to 100 do begin
if (x mod 2) = 0 then writeln(x);
end;
level 2
for x := 1 to 100 do beginif (x mod 2) = 0 then writeln(x);end;
it worked!, thank you so much my guy!
but why it have to be mod?, not div or /?
level 2
The 1st example is more efficient than the 2nd. (50 less iterations to be exact)
level 1
The problem is that in the for loop, you try to change the variable that is used in the loop (the «x» variable). You cannot change the variable that is used in the for the loop. u/tecnorober gave one solution to the problem, but another one that you can use (and allows changing the variable used for the loop) is like this:
var
x:integer;
begin
x := 1;
while x =< 100 do
begin
writeln(x);
x:=x+2;
end;
end;
With a while loop, you can change the variable that was used for the loop.
level 2
i know, but the assignment is to use for loop, but thx anyway!
level 1
I love the syntax for Pascal. I dont know if i could learn another language, but the thing is, u ask so many and they tell u Pascal is ancient or dead just like Visual Basic.
So i dont know.
There is scripting like Python and Bash for linux/Solaris, but not sure, i mean Pascal has the whole Lazarus project going for it, surely it cant be that obsolete ?
level 2
It is not very popular and thats all that counts. C and pascal were released just 1 year apart, so age isn’t a good measure for a language. People only say that pascal is dead because it isn’t very popular.
My recommendation is, if you want a job then learn something else. If you just want to do programming as a hobby, then pascal is more than enough.
In my experience(and i am NOT a professional programmer), nothing can beat pascal/lazarus when it comes to cross platform gui programming.
About Community
Pascal, Freepascal (FPC), Lazarus IDE, Turbo Pascal, Delphi, all dialects of Pascal
Правила раздела!
1. Заголовок или название темы должно быть информативным !
2. Все тексты фрагментов программ должны помещаться в теги [code] … [/code] или [code=pas] … [/code].
3. Прежде чем задавать вопрос, см. «FAQ» и используйте ПОИСК !
4. НЕ используйте форум для личного общения!
5. Самое главное — это раздел теоретический, т.е. никаких задач и программ (за исключением небольших фрагментов) — для этого есть отдельный раздел!
|
Сообщение |
|
Гость |
По идее когда число повторений неизвестно, For использовать нельзя, но может все-таки как-нибудь можно?
|
|
|
volvo |
Сообщение |
Гость |
bhldr, нет… Ты действительно должен знать точное число итераций, а здесь ты этого не можешь знать из-за рекуррентности формулы (последующий элемент зависит от предыдущего). Кстати, а чем Repeat Until не нравится? Он побыстрее For будет (при использовании Турбо Паскаля…) |
|
|
bhldr |
Сообщение |
Гость |
Мне RepeatUntil нравится, просто задание у меня такое: нужно эту тему представить в трех циклах, а я не врубаюсь, как ее в For перебить. |
|
|
volvo |
Сообщение |
Гость |
Извращение, конечно, но… Сам просил: const |
|
|
bhldr |
Сообщение |
Гость |
Спасибо, всё круто. Только maxIter надо по-видимому сделать переменной, зависящей от eps, иначе если очень маленькую eps задать, то цикл рано закончится. |
|
|
klem4 |
Сообщение |
Perl. Just code it!
Группа: Пользователи
Репутация: |
хе-хе ну раз про извращения разговор пошел, то можно и вот так : const добвлено : Volvo, я просто с просони забыл убрать эту переменную и проверку, естественно она в таком случае не нужна. Сообщение отредактировано: klem4 — 24.10.2005 13:09 ——————— perl -e ‘print for (map{chr(hex)}(«4861707079204E6577205965617221″=~/(.{2})/g)), «n»;’ |
|
|
volvo |
Сообщение |
Гость |
klem4, это не извращение, а невнимательность: ... stop в таком случае вообще не нужен |
|
|
Digitalator |
Сообщение |
Бывалый
Группа: Пользователи
Репутация: |
а вот вам супер извращение, по идее должно работать Код for i:=1 to 1 do ——————— In byte we trust |
|
|
Altair |
Сообщение |
Ищущий истину
Группа: Пользователи
Репутация: |
Позволю себе оффтоп. Цитата for i:=1 to 1 do еще одна оригинальная конструкция улетает в копилку… Хотя ИМХО возможно еще по адресное хранения переменный, типа for i:=1 to 1 do ! ——————— Помогая друг другу, мы справимся с любыми трудностями! |
|
|
volvo |
Сообщение |
Гость |
Олег, а вот это не срабатывает (на FPC, в частности) Цитата Error: Illegal assignment to for-loop variable i , хотя меняю я X … |
|
|
Altair |
Сообщение |
Ищущий истину
Группа: Пользователи
Репутация: |
хм.. круто! ——————— Помогая друг другу, мы справимся с любыми трудностями! |
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
Связь с администрацией: bu_gen в домене octagram.name