На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
... (продолжение следует) ...

Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...
Модераторы: jack128, D[u]fa, Shaggy, Rouse_
  
> Проблема с циклом for, Непонятный глюк с счетчиком
    Приветствую всех.

    Перейду сразу к делу.
    ExpandedWrap disabled
      // Получаем префикс времени
      function GetTimePrefix(N: Integer): String;
      const
        pref: array [0..6] of string = (' г. ', ' м. ', ' н. ', ' д. ', ' ч. ', ' мин. ', ' сек. ');
        del: array [0..6] of Integer = (31536000, 2592000, 604800, 86400, 3600, 60, 1);
      var
        a: array [0..6] of Integer;
        i: integer;
      begin
        Result := '';
        a[6] := N;
       
        for i := 0 to 5 do
        begin
          a[i] := a[6] div del[i];
          a[6] := a[6] mod del[i];
          if a[i] <> 0 then
            Result := Result + IntToStr(a[i]) + pref[i]
        end
      end;


    После строки
    ExpandedWrap disabled
      for i := 0 to 5 do

    счетчик при первой итерации устанавливается в i=6, а затем спускается вниз. Замечено, что если поставить
    ExpandedWrap disabled
      for i := 0 to N do

    то счетчик примет при первой итерации значение i=N+1.

    В чем причина?! Более в коде под "i" никакой другой переменной нет. Поясните, пожалуйста
      А в чем проблема то, так и должно быть.
      procedure TWorld.GetMoney;
      label m1;
      Begin
      m1:
      development.development.development;
      goto m1;
      end;
        Если от направления обхода ничего не зависит, то компилятор делает так, как ему приятнее.
          В том то и дело, что зависит. Приходится менять код под компилятор. От конструкции for пришлось перейти к while.

          ExpandedWrap disabled
              i := 0;
              Result := '';
              while i <= High(del) do
              begin
                a[i] := N div del[i];
                N := N mod del[i];
                if a[i] <> 0 then
                  Result := Result + IntToStr(a[i]) + pref[i];
                inc(i)
              end
            ExpandedWrap disabled
                  ATime := Now;
                  s := FormatDateTime('yyyy г. m м. ', ATime) + IntToStr(WeekOfTheYear(ATime))
                    + ' н. ' + FormatDateTime('d д. hh ч. nn мин. s сек.', ATime);

            не подходит?
            Beware the wild rabbit.
              >В том то и дело, что зависит
              Да, действительно. Похоже, что компилятор этого не заметил.
              Впрочем, код всё равно не вполне корректный, т.к. дает только приблизительную раскладку по временным периодам.
                Цитата ProESM @
                В том то и дело, что зависит.


                Не настолько зависит, как ты думаешь. Последствия разворота цикла компилятор учитывает.

                Если тебе это мешает при отладке - отключи оптимизацию кода (в опциях проекта). Не забудь только включить для релиза.

                Добавлено
                Цитата MBo @
                Похоже, что компилятор этого не заметил.


                Нет, просто он вообще не использует i для доступа к массивам. Если ты посмотришь на ассемблерный код, то увидишь, что компилятор сохраняет в ESI/EDI начала обоих массивов и на каждой итерации их увеличивает на 4. Сложение эффективнее умножения (которое произошло бы при использовании индексации через i).

                Само i используется только как счётчик цикла. В теле цикла к нему обращений нет (в ассемблерном коде).

                Вы зря недооцениваете Delphi-сий оптимизатор. Он, конечно, не фонтан, но и не настолько же плох!
                Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
                  Цитата CodeMonkey @
                  Нет, просто он вообще не использует i для доступа к массивам.

                  И не только для доступа к массивам.
                  Вот сейчас ищу проблему, которая записана в багтрекере. Прохожу под отладчиком код:
                  ExpandedWrap disabled
                        for i:=0 to Nc-1 do begin
                          Group:=TGroup.Create;
                          with Group do begin
                            BlockRead(FF,ID_Group,SizeOf(Integer));
                            BlockRead(FF,GroupName,SizeOf(ShortString));
                            BlockRead(FF,ID_Group,SizeOf(Integer));
                            if ID_Group >= MaxID_Group then MaxID_Group:=ID_Group+1;
                            BlockRead(FF,NN,SizeOf(Integer));
                            SetLength(Doors,NN);
                            for k:=0 to NN-1 do
                              BlockRead(FF,Doors[k],SizeOf(Integer));
                            BlockRead(FF,NN,SizeOf(Integer));
                            SetLength(TZs,NN);
                            for k:=0 to NN-1 do
                              BlockRead(FF,TZs[k],SizeOf(Integer));
                          end;
                          AddGroup(Group);
                        end;

                  Итератор цикла (переменная i) в теле цикла нигде не используется. Так и WatchList и Hint показывает на любой итерации одно и то же значение для этой переменной - 28, оставшееся от предыдущего цикла в той же самой процедуре. Т.е. уж настолько не используется, что мне отладчик даже никак не может показать на какой итерации цикла я в данный момент нахожусь.
                  Сообщение отредактировано: northener -
                  Цитата
                  Но только лошади летают вдохновенно.
                  Иначе лошади разбились бы мгновенно!
                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                  0 пользователей:


                  Рейтинг@Mail.ru
                  [ Script Execution time: 0,4338 ]   [ 17 queries used ]   [ Generated: 18.03.19, 17:52 GMT ]