Блог пользователя egor-belikov

Автор egor-belikov, 13 лет назад, По-русски

Вопрос исключительно для Дельфистов и Паскалистов.

Возможно, не только у меня бывало, что счетчик в цикле начинал вести себя, как ему хочется, а не хочется мне. Пример:

for i := 1 to n do

  writeln('Bla-bla-bla');

При этом i идет от n + 1 до 2. Или еще какой-то порядок, неизвестный ни мне, ни отладчику.

Как с этим бороться?

  • Проголосовать: нравится
  • 0
  • Проголосовать: не нравится

13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Напишите конкретный пример, на котором цикл работает неверно.

Возможно, вы изменяете значение переменной внутри цикла.
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    for a := 1 to m do
      for j := 0 to length(coor) - 1 do
         if coor[j][0] = buses[a].t then
           for k := 1 to length(coor[j]) - 1 do
              buses[a].res := (buses[a].res + buses[numbs[coor[j][k]]].res) mod eps;
13 лет назад, # |
Rev. 8   Проголосовать: нравится 0 Проголосовать: не нравится

Директива компилятора {\$O-} убирает оптимизацию, которая и является причиной таких спецэффектов.
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
{O + } / {O-}?
Попробуйте второе. Если проблема убьётся, значит, как обычно, виноват оптимизатор :)
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Стоит D+,O-. 

Продолжает неправильно работать.

  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Тогда ещё полезно знать, какой компилятор вы используете.
    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Delphi 7.
      • 13 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        Это вам дебагер показывает ?
        Не стоит ему верить.
        • 13 лет назад, # ^ |
          Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

          Почему?

          А кому мне еще верить, неправильному ответу?

          • 13 лет назад, # ^ |
            Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

            Дебагер часто лагает, это довольно распространенная проблема. Попробуйте в цикле выводить i в файл. Если все выведется нормально(1..n) - значит виноват дебагер(он просто показывает ложную информацию))
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Тут, кажется, причина в другом. Дело в том, что ф-ця length работает по разному в Делфи и Турбо Паскале. В Делфи значение этой переменной хранится в нулевой ячейке переменной, описывающей строку.
    Поэтому при неаккуратной работе со строками (особенно с st[0] - нулевой ячейкой литерного массива) может происходить всё что угодно.
    Более конкретно, не имея всего кода программы, сказать трудно.
    Кажется так, впрочем, Ваш результат нахождения причины такого поведения мне тоже интересен.
    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      coor - не строка, а список списков.
      • 13 лет назад, # ^ |
        Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

        А что тогда по Вашему length?
        Ведь ведёт себя эта функция по прежнему так, как сказано выше - она берёт свое значение с нулевой ячейки.
        UPD: Если Вы, конечно, не написали свою функцию под таким именем, - тогда все мои высказывания выше можно не учитывать. Я говорил о встроенной в Делфи ф-ции и её неадекватном поведении.
        • 13 лет назад, # ^ |
          Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

          Автоматически список (k : array of integer) нумеруется от 0 до length(k) - 1 элемента, по-сишному.

          UPD: Ни одной функции в программе.
          • 13 лет назад, # ^ |
            Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

            Ну так объявление k : array of integer создаёт динамический массив, размер которого может меняться во время работы программы.
            В цикле 
            for j := 0 to length(coor) - 1 do значение length(coor) вычисляется только один раз до начала цикла и не перевычисляется в работе цикла, даже если размер массива изменился.
            Похоже из-за этого всё, видимо, и происходит. Хотя опять же - не имея полного кода программы точнее ответить затруднительно.

13 лет назад, # |
  Проголосовать: нравится +1 Проголосовать: не нравится
It isn't a normal behaviour...

But, why "unknown for me and debugger"? Just try for i:=1 to n do writeln(i);
This suffices to check the correct behaviour of the loop.

Also you should check if you do something with "i" inside the loop.
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
в делфи 7 где-то в свойствах проекта, я уже не помню где, можно убрать галочку "Optimization" тогда в дебагере многие "кривые" переменные становятся "ровными".
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Напишите пожалуйста очень короткую но целую программульку демонстрирующую ваш вопрос (не фрагмент как выше), тогда коллегам не придётся заниматься телепатией и лечением по фотографии.
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
может у вас переменная int64?
у меня до сих пор  смутное отвращение к int64 в качестве счетчика for цикла, кажется были какие-то неприятности, причем на дельфи
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    int64 в качестве счетчика for цикла использовать в Делфи нельзя.
    Для переменных такого типа применимы только циклы while и repeat ... until ...
    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      действительно не компилируется в delphi/fpc/kylix 
      видимо я ошибся