Ошибка ли это?

Две программы, обрабатывающие “дурака” при вводе, вроде одинаковы, должны отправлять назад, но первая программа при вводе числа не соответствующему месяцу (например 14) уже следующий раз при правильном (например 3) опять требует ввода?! Вторая - без проблем… Первая:

program tt;
label n1;
var a:byte;
begin
n1:
   readln(a);
   case a of
    1,2,12:writeln('Зима');
      3..5:writeln('Весна');
      6..8:writeln('Лето');
     9..11:writeln('Осень');
    else
      begin
        writeln('Такого номера месяца нет');
        writeln('Повторите ввод');
        goto n1;
      end;
   end; 
 end. 

Вторая:

program tt;
var a:byte;
begin
 repeat
   readln(a);
   case a of
    1,2,12:writeln('Зима');
      3..5:writeln('Весна');
      6..8:writeln('Лето');
     9..11:writeln('Осень');
    else
      begin
        writeln('Такого номера месяца нет');
        writeln('Повторите ввод');
      end;
   end; 
 until(a>=1)and(a<=12);  
end.

Используйте markdown для вставки кода:

```
код
```

То что вы вставили нечитабельно.

1 лайк

Проверили. Не требует

Вы точно проверили? Да, второй алгоритм работает безупречно! Меня интересует первый алгоритм?! В первом алгоритме, в случае, когда я введу сразу число от 1 до 12 у меня проблем не будет, но стоит мне ввести (например) 14, у меня идет обработка, что такого месяца нет и идет на метку n1… но теперь, если я ввожу опять число от 1 до 12 - он меня “посылает” опять на ввод, хотя ДОЛЖЕН выдать пору года?! У меня версия 3.7.1 … ?!

Вы этот код где брали? В книге 1980 года издания? Но ведь уже тогда учили писать без goto… Ужас какой-то…

1 лайк

Нормальный код. Мы не видим каких-то ошибок в работе goto

Так программа с goto зацикливает, когда хочешь ввести правильный ответ (от 1 до 12) после того, как в ведёшь один неправильный :slight_smile:

Я разве что-то говорил по поводу того, что goto неправильно работает? Я удивляюсь стилю программирования, когда в 2021 году показывают код уровня полувековой давности. Ведь кто-то же научил так писать…

Ну и где тут зацикливание?

1 лайк

А вообще, на PascalАВС.NЕТ это вот так пишется примерно:

##
var a: integer;
repeat
  a := ReadInteger;
  case a of
    1, 2, 12: Print('Зима');
    3..5: Print('Весна');
    6..8: Print('Лето');
    9..11: Print('Осень');
  else
    Writeln('Такого номера месяца нет', NewLine, 'Повторите ввод')
  end
until a in 1..12

a in 1..12 это, конечно, красиво, но тут это дубль уже проверенного условия. В реальных ситуациях такое приводит к сложно ловимым багам, если, к примеру, поменяется набор вариантов case. Лучше использовать else чтоб выбирать куда идти дальше:

##
repeat
  var a := ReadInteger('Номер месяца:');
  case a of
    1..2, 12: 'Зима'.Print;
    3..5: 'Весна'.Print;
    6..8: 'Лето'.Print;
    9..11: 'Осень'.Print;
  else
    $'Такого номера месяца нет{NewLine}Повторите ввод'.Println;
    continue;
  end;
  break;
until false;
2 лайка

Да, красиво, только меня интересует почему с goto не работает?!. Хотя по идее должно работать… Или в операторе case безусловный переход не работает…

Странно, а у меня при 9.опять выдаёт Нет такого месяца… Какая у вас операционная система.? Может это из-за неё… Я уже вообще ничего не понимаю…

ОС не при чём, а вот версия компилятора может влиять. Какая сейчас стоит? Попробуйте обновится отсюда:
http://pascalabc.net/ssyilki-dlya-skachivaniya

Да, переставил с 3.7.1 на 3.8.1 и все пошло!!! Спасибо! У нас в Беларуси на http://dl.gsu.by для тестов тоже стоит компилятор 3.7.1 поэтому некоторые задачи мы пропускаем на freePascal

Вполне нормальная версия. Да, многого там нет, но это потому, что Беларусь не считается с рекомендациями разработчиков PascalАВС.NЕТ, которые на официальном сайте указали минимально рекомендуемую версию 3.8. Вот и продолжаете писать коды с древнемохнатыми Program, Label и тому подобным. Впрочем, если кто-то хочет сидеть в технологиях прошлого века - как, говорится, вольному - воля…

2 лайка

ну к стати обливать goto смысла не вижу. это такой же оператор, как и любой другой.

другое дело, что любой оператор нужно применять уместно. а от того, что этим оператором легко выстрелить себе в ногу, он сам по себе хуже не становится

1 лайк

Этот оператор снижает наглядность кода. В высокоуровневых языках его безосновательное использование свидетельствует лишь о низком уровне культуры программирования, либо недостатке знаний и умений. В данном случае применение goto совершенно неоправданно.

Ну и “кстати” пишется слитно. Кроме того, “к стати” имеет совсем не тот смысл, который Вы, насколько я понимаю, хотели вложить в свою фразу. Загляните в словарик, что такое “стать”.

1 лайк

снижает наглядность кода не операторы, а их некорректное применение.

ну то есть Вы всё таки согласны, что есть случаи, где применение данного оператора обоснованно?

да-да, спасибо за лекцию по незначительной ошибке

2 лайка