В пошаговом работает, а в обычном сбоит

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Ответить
Sanek222
незнакомец
Сообщения: 3
Зарегистрирован: 30.05.2016 09:08:28

В пошаговом работает, а в обычном сбоит

Сообщение Sanek222 »

Ребят, привет. Я совсем новый в этом деле. Учу Паскаль. Вот уже несколько программ показало следующее: при отладке консольной программы в пошаговом все четко работает, а при обычном запуске не корректно выполняется. Например повторы одного результата заданное кол-во раз. или вместо нескольких результатов выходит только 1. Думаю что-то в настройках. Но методом тыка ничего не решил. еще раз отмечу-в пошаговом работает все как надо
p.s. FPC 3.0.0 , win XP sp3
скалогрыз
долгожитель
Сообщения: 1804
Зарегистрирован: 03.09.2008 02:36:48

Сообщение скалогрыз »

ошибка в программе
resident
энтузиаст
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Сообщение resident »

Sanek222
Для новостей есть твиттер.
Или у вас какой-то вопрос? Что-то не вижу ни строки кода, ни вопроса.
Или это крик души? Тогда да, скажу что отладчик не лишен недостатков. Пример:
Отладка - Количество просматриваемых элементов массива
Но при всех недостатках я еще не встречал ситуации, когда бы отладчик что-то сделал неверно.
Sanek222
незнакомец
Сообщения: 3
Зарегистрирован: 30.05.2016 09:08:28

Сообщение Sanek222 »

например это в отладке работает, а при запуске выполнения дает только 1 результат из множества.
var sn1,sn2:set of 1..50; x,y:byte;

begin
x:=0;
sn1:=[1..50]; sn2:=sn1;
for x:=1 to 20 do begin
randomize;
y:=random(50);
if [y]<=sn2 then write(y:4);
sn2:=sn1-[y];
end;
readln
end.
resident
энтузиаст
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Сообщение resident »

Код: Выделить всё

program Project1;

var
  sn1, sn2: set of byte;
  x,y:byte;

begin
sn1 := [1..50];
sn2 := sn1;
randomize;
for x:=1 to 20 do
  begin
    y := random(50);
    if y in sn2 then
      WriteLn(y);
    sn2 := sn1 - [y];
  end;
readln;
end.


Добавлено спустя 10 минут 15 секунд:
Подтверждаю, творится чертовщина. Если вынести randomize из цикла - вроде работает.
SSerge
энтузиаст
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Сообщение SSerge »

resident писал(а):Если вынести randomize из цикла - вроде работает.


А ее и надо вынести из цикла.
В ином случае y будет с вероятностью 90:1 одним и тем же значением.
Потому что randomize инициализирует счетчик из текущего значения системного таймера, а тикнет он гораздо позже, чем просчитается цикл от 1 до 20.
Никакой мистики.
resident
энтузиаст
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Сообщение resident »

SSerge писал(а):В ином случае y будет с вероятностью 90:1 одним и тем же значением.

Под отладкой все ок.
Но не это самое странное, а то что Лазарус не выводит эти пусть и одинаковые значения, вобще, никак. Как будто и нет цикла с write вовсе.
скалогрыз
долгожитель
Сообщения: 1804
Зарегистрирован: 03.09.2008 02:36:48

Сообщение скалогрыз »

resident писал(а):Под отладкой все ок.
Но не это самое странное, а то что Лазарус не выводит эти пусть и одинаковые значения, вобще, никак. Как будто и нет цикла с write вовсе.


эти значения будут выводится только, если "y in sn2". А этот самый y уже убрался при первой проходе цикла.
Т.к. randomize() сбрасывает randseed в одно и тоже значение каждый раз в цикле, то и random возвращает одинаковые значения для "y"

убедится на практике совсем не сложно:

Код: Выделить всё

var 
  sn1,sn2:set of 1..50; x,y:byte;
begin
  x:=0;
  sn1:=[1..50]; sn2:=sn1;
  for x:=1 to 20 do begin
    randomize;
    y:=random(50);
    writeln('y= ',y,' ');
    if [y]<=sn2 then write(y:4);
      writeln;
    sn2:=sn1-[y];
  end;
  readln
end.


В пошаговом режиме, из-за randomize() генерирует разные числа, потому что проходит достаточное количество времени между итерациями цикла.


тут нужно заметить что

Код: Выделить всё

  y:=random(50);

имеет смысл поменять на

Код: Выделить всё

  y:=random(50)+1;

всё-таки наборы sn1 и sn2 от 1 до 50, а не от 0 до 49.
Sanek222
незнакомец
Сообщения: 3
Зарегистрирован: 30.05.2016 09:08:28

Сообщение Sanek222 »

Спасибо за урок. Всем откликнувшимся респект :)
resident
энтузиаст
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Сообщение resident »

скалогрыз писал(а):В пошаговом режиме, из-за randomize() генерирует разные числа, потому что проходит достаточное количество времени между итерациями цикла.

Да, если добавить паузу, то вычисляются различные "у". Значит отладчик так тормозит.

Код: Выделить всё

y:=random(50);
Sleep(y);
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

resident писал(а):Значит отладчик так тормозит.


отладчик и должен тормозить... работа у него такая.
Аватара пользователя
debi12345
долгожитель
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Сообщение debi12345 »

Может быть в проге есть какое-то "race condition", которое при останове выруливает в правильную сторону, и в неправильную в штатном режиме ?
SSerge
энтузиаст
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Сообщение SSerge »

debi12345 писал(а):Может быть в проге есть какое-то "race condition"


В проге есть грубая ошибка программирования, нарушающая прямое предписание описания библиотеки RTL о том, что генератор случайных чисел инициализируется единственный раз до применения его последовательностей:

Код: Выделить всё

 for x:=1 to 20 do begin
    randomize;
    y:=random(50);
    writeln('y= ',y,' ');
    if [y]<=sn2 then write(y:4);
      writeln;
    sn2:=sn1-[y];
  end;
Ответить