Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Круглый стол
  
Правила КС
>> Настройки

Фильтр вопросов
>> Новые вопросы
отслеживать по
>> Новые ответы

Избранное

Страница вопросов
Поиск по КС


Специальные проекты:
>> К л ю к в а
>> Г о л о в о л о м к и

Вопрос №

Задать вопрос
Off-topic вопросы

Помощь

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  22:49[Войти] | [Зарегистрироваться]
Ответ на вопрос № 36060

26-09-2005 06:15
1. Есть всем известный цикл For I:=1 to Func(...) do ..., где Func - некоторая функция, выполняющая сложные вычисления. Будет ли эта функция выполняться каждую итерацию цикла, или Delphi сохранит значение этой функции на начало цикла в некоторой скрытой переменной и затем будет сравнивать счетчик именно с ней? То есть стоит ли использовать код, подобный такому:

Temp:=Func(...);
For I:=1 to Temp do ...;


или он будет идентичен вышеприведенному?
2. В справке Delphi сказано:
>>> After the for statement terminates, the value of counter is undefined
Что означает, что значение счетчика после цикла не определено. Но я обычно использую такую конструкцию:

For I:=1 to 10 do ...;
ShowMessage(inttostr(I));


И код показывает значение 11, то есть всегда определенное значение (на 1 больше последнего значения). Я неправильно понимаю текст справки, или в чем дело? Я не хочу, чтобы в один прекрасный день мои программы перестали работать из-за каких-то модификаций Borlandа.
К сожалению, поиск по КС на ключевое слово For дает слишком много ссылок, а как конкретизировать запрос я не знаю.

[+] Добавить в избранные вопросы

Отслеживать ответы на этот вопрос по RSS

Ответы:


Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице.
Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.

26-07-2006 06:59
>>> Или я что-то не понял, или автор той статьи ошибся?
Если посмотреть на страницу внимательно, то в самом верху можно прочитать:
Внимание! В статье имеются неточности и некорректные утверждения. 
примечание администрации


Ответить на этот вопрос очень просто: как я уже говорил, надо взять и написать тестовую программу.

26-07-2006 06:26 | Сообщение от автора вопроса
Прочитал статью http://www.delphimaster.ru/articles/optimization.html и меня смутила такая фраза:
Delphi будет при каждой итерации вызывать метод count, вычитать из результата 1
Но Границы цикла for вычисляются только один раз - это стандарт языка Паскаль. Или я что-то не понял, или автор той статьи ошибся?

30-09-2005 05:25 | Сообщение от автора вопроса
>>> Границы цикла for вычисляются только один раз
Это, однако, хорошо, я сам догадывался, просто не был уверен.
>>> Оптимизатор может изменить код так
Вредная штука этот оптимизатор! И переменные сплошь и рядом удаляет и много чего еще делает. В Ассемблере такого нету. К счастью, а может - к сожалению.
>>> Например, в Perl переменная цикла вообще имеет контекст видимости только внутри цикла
Это сделано зря. ИМХО, конечно.
>>> Вот в си по-моему к переменной после цикла
Это еще кто придумал??? Всегда обращался... Там ведь цикл for(i=0;i<=10;i++)statement; фактически организован как i=0;while(i<=10){statement;i++} и такое ограничение не может иметь места. И грозного предупреждения в Help там тоже нет!
>>> если в цикле нет явных команд обращения к переменной цикла
А для чего тогда цикл? 10 раз вывести Hello, world? А A[I] - это уже адрес. И Си, например, вообще при оптимизации выкидывает индекс и работает с указателями (если я еще помню Си)
>>> используй WHILE или REPEAT-UNTIL
Так и приходится делать. Спасибо. А то я думал, это баг компилятора, а это, оказывается, вроде фичи, если не стандарт. Обсуждение можно считать закрытым.

28-09-2005 00:08
От себя добавлю, что в весрии с D-5 цикл FOR в 90% случаев превращается в коде в цикл WHILE с декрементом от N до 0. Так что условие окончания цикла он вычисляет один раз - в начале, и уже не проверяет.
Более того, если в цикле нет явных команд обращения к переменной цикла (например, она используется только как индекс массива, но не в вычислениях), то в отладчике просмотреть ее будет очень проблематично.
Простейший пример:

Sum := 0;
for i:=0 to 10
  do
    Sum := Sum + A[i];


В отладчике на первом шаге имеем I=10, на второй - 9, на последней - 0, хотя на первом шаге извлекается именно A[0], на втором - A[1], и так далее. После цикла переменная i в отладчике вовсе отсутствует.
Может, у вас пример именно так работать и не будет, я его чересчур упростил. Но когда я отлаживал свою прогу - чуть голову не сломал, когда натолкнулся на данный эффект.

27-09-2005 02:17
Katenok-13:

Cоздал новый проект, положил на форму кнопку и метку, в обработчике нажатия кнопки написал такой текст:

procedure TForm1.Button1Click(Sender: TObject);
  var I,N:Integer;
    begin
      N:=10;
      for I:=1 to N do
        begin
          if I=1 then
            Inc(N);
          if I=11 then
            Beep;
          Label1.Caption:=IntToStr(I)
        end;
    end;



После нажатия кнопки в Label1 оказывается текст "10", точка останова на Beep не срабатывает. Включение/выключение оптимизации на результат не влияет. На строке Inc(N) компилятор выдаёт подсказку Value assigned to 'N' never used. Эксперимент проделан в Delphi 4, 5, 6 и 7 - везде результат одинаков.

Вот в си по-моему к переменной после цикла и нельзя обратиться.

Клюква. Вы цикл for в С хоть раз видели? Там это вообще разновидность while.

26-09-2005 22:11
Не знаю, как насчет вычисления только один раз, но в некоторых программах я встречала конструкцию типа


n:=3;
for i:=1 to n do
  begin
    if i=2 then inc(n);
    ...
  end;


И оно именно что увеличивало границу цикла, т.е. она все-таки вычисляется каждый раз.

А насчет "FOR-Loop variable '<element>' may be undefined after loop", то help общий и для CBuilder'а, и для Delphi. Вот в си по-моему к переменной после цикла и нельзя обратиться.

26-09-2005 07:40 | Комментарий к предыдущим ответам
А так пришлось ограничиться грозным предупреждением в Help.
Ну не только в Help, варнинги тоже исправно выдаются "FOR-Loop variable '<element>' may be undefined after loop".

26-09-2005 07:22
Присоединяясь за компанию, могу сказать, что обращение к переменной цикла нехорошо также с точки  зрения структурного программирования. Например, в Perl переменная цикла вообще имеет контекст видимости только внутри цикла, и снаружи ее просто нет. Если бы в Pascal было понятие переменной контекста блока, наверняка тоже сделали бы именно так. А так пришлось ограничиться грозным предупреждением в Help.


26-09-2005 06:32
1. Насколько я понимаю, вызов функции будет осуществляться один раз. Но проще написать тестовую прогу и поглядеть (вставить break-point в функцию или глянуть код под отладчиком).

2. Если не хочешь, чтобы прога накрылась, то не пользуйся недокументированными возможностями. В частности, в современных Дельфях (где оптимизирующие компиляторы) цикл может прокручиываться в обратную сторону (так выгоднее). Более того, переменная цикла может быть просто удалена после того, как цикл отработает.

Если тебе нужно значение после завершения цикла, то используй WHILE или REPEAT-UNTIL с самостоятельно выполняемым инкрементом.

26-09-2005 06:30
1. Границы цикла for вычисляются только один раз - это стандарт языка Паскаль.

2. Оптимизатор может изменить код так, что переменная будет иметь не то значение, которое вы ожидали. И если он сто раз этого не сделал, то не факт, что не сделает и в сто первый.

Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
Жили у бабуси два веселых гуся. Один белый, другой КАКОЙ?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.
Тип сообщения:
Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве

    Страница избранных вопросов Круглого стола.
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования