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

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

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

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

Сообщение Sanek222 » 30.05.2016 10:19:29

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

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

Сообщение скалогрыз » 30.05.2016 10:36:02

ошибка в программе
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

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

Сообщение resident » 30.05.2016 11:54:04

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

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

Сообщение Sanek222 » 30.05.2016 17:34:34

например это в отладке работает, а при запуске выполнения дает только 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.
Sanek222
незнакомец
 
Сообщения: 3
Зарегистрирован: 30.05.2016 10:08:28

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

Сообщение resident » 30.05.2016 18:32:39

Код: Выделить всё
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 из цикла - вроде работает.
resident
энтузиаст
 
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

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

Сообщение SSerge » 30.05.2016 19:09:23

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


А ее и надо вынести из цикла.
В ином случае y будет с вероятностью 90:1 одним и тем же значением.
Потому что randomize инициализирует счетчик из текущего значения системного таймера, а тикнет он гораздо позже, чем просчитается цикл от 1 до 20.
Никакой мистики.
SSerge
энтузиаст
 
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

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

Сообщение resident » 30.05.2016 19:16:44

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

Под отладкой все ок.
Но не это самое странное, а то что Лазарус не выводит эти пусть и одинаковые значения, вобще, никак. Как будто и нет цикла с write вовсе.
resident
энтузиаст
 
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

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

Сообщение скалогрыз » 30.05.2016 19:42:04

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.
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

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

Сообщение Sanek222 » 31.05.2016 10:47:40

Спасибо за урок. Всем откликнувшимся респект :)
Sanek222
незнакомец
 
Сообщения: 3
Зарегистрирован: 30.05.2016 10:08:28

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

Сообщение resident » 31.05.2016 10:55:01

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

Да, если добавить паузу, то вычисляются различные "у". Значит отладчик так тормозит.
Код: Выделить всё
y:=random(50);
Sleep(y);
resident
энтузиаст
 
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

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

Сообщение Лекс Айрин » 31.05.2016 11:12:51

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


отладчик и должен тормозить... работа у него такая.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

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

Сообщение debi12345 » 31.05.2016 12:26:13

Может быть в проге есть какое-то "race condition", которое при останове выруливает в правильную сторону, и в неправильную в штатном режиме ?
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5752
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

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

Сообщение SSerge » 31.05.2016 13:51:12

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;
SSerge
энтузиаст
 
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 12

Рейтинг@Mail.ru