Замечания и предложения

Не похоже чтоб вы сильно разобрались в ситуации перед тем как писать:

  1. Вы везде написали Pascal ABC, хотя это старая версия, с другими разработчиками, на этом форуме и на том репозитории гитхаба рассматривается PascalABC.Net.
  2. Я не уверен что значит ваше:
Запускаем с перенаправлением ввода-вывода:
source.exe <input.txt >output.txt

но я написал туже самую программу с тем как это делается в PascalABC.Net и всё работает как должно:

begin
  Reset(input, '0.txt');
  var k: longint;
  Readln(k);
  writeln(2 * k);
end.

хотя приведённая andrew-boyarshin программа всё ещё не работает. Скорее всего вы говорите совершенно о другом случае. 3. Вы писали про какие то авторские программы… Что это, где? Если пишете, приведите хотя бы 1 не работающую целиком.

Спасибо за ответ.

  1. Речь идёт про Pascal ABC.NET v3.2.0.1514. Компиляция через pabcnetcclear.exe. .NetFramework 4.0.

  2. source.exe <input.txt >output.txt - это запуск из командной строки с перенаправлением ввода-вывода в файлы. Ваша программа прямым чтением из файла по Reset(input, '0.txt'); работает, да. Но в олимпиадных задачах по программированию часто в условии требуется консольный ввод-вывод. Особенно для простых задач. Так и писать короче, и отлаживать проще новичкам. Чтобы такие решения автоматически проверять на наборе тестов, тестовый движок производит запуск откомпилированного решения с перенаправлением в файлы, как указано выше. Такой способ намного проще и надёжнее, чем слишком сложно автоматизируемое предварительное внедрение в исходник команд перенаправления ввода-вывода reset/rewrite, и универсально подходит для любого из поддерживаемых языков программирования. С другими языками проблема с концевыми переводами строки до сих пор не встречалась, поэтому велика вероятность, что она будет периодически проявляться при импорте готовых задач с соревнований по программированию (IOI, ACM, USACO, региональные олимпиады и т.д.), авторы которых тоже могут упускать концевые переводы строк в тестах. Будет получаться, что на прочих языках аналогичные решения работают, а на Pascal ABC.NET с readln - нет.

  3. Резюмируя, необходимо, чтобы исходник

var
  k: longint;
begin
  readln(k);
  writeln(2*k);
end.

запущенный в режиме файлового перенаправления source.exe <input.txt >output.txt, мог успешно отработать с файлом input.txt, содержащим только один байт с символом 1, например.

1 лайк

На Github написал - повторю здесь:

Пока для олимпиад в PABCSystem.pas сделайте следующую правку: вместо

procedure IOStandardSystem.readln;
begin
  while CurrentIOSystem.read_symbol <> END_OF_LINE_SYMBOL do;
end;

напишите

procedure IOStandardSystem.readln;
begin
  while True do
  begin
    var sym := CurrentIOSystem.read_symbol;
    if (sym = END_OF_LINE_SYMBOL) or (sym = char(-1)) then
      exit;
  end;
end;

и перекомпилируйте PABCSystem, поместив pcu в Lib поверх старого Все тесты проходят.

А мы еще потестируем.

2 лайка

Спасибо, что прониклись и поправили.

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

Иначе будем ждать выпуска очередной версии.

Кстати, а почему из Until не доступно то, что определяется после Repeat и надо переменную заранее описывать? Вот так работает

procedure IOStandardSystem.readln;
var sym : char;
begin 
 Repeat
  sym := CurrentIOSystem.read_symbol;
 Until (sym = END_OF_LINE_SYMBOL) or (sym = char(-1)) 
end;

а так выдаёт ошибку

procedure IOStandardSystem.readln;
begin 
 Repeat
  var sym := CurrentIOSystem.read_symbol;
 Until (sym = END_OF_LINE_SYMBOL) or (sym = char(-1)) 
end;

Потому что пространство имён

Можете пожалуйста сделать чтоб паскаль запоминал положения(и состояние, то есть Maximised) своего окна и окна помощи при их закрытии, а так же настройки нижнего элемента показывающий “окно ввода”, “список ошибок” и т.п.? Каждый раз при запуске настраивать не долго но муторно…

1 лайк

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

begin
  var d := new Dictionary<integer, string>;
  d.Add(1, 'a');d.Add(2, 'a');d.Add(3, 'a');
  if d.ContainsKey(2){первый поиск} then
    writeln(d[2]{второй поиск});
    //writeln(d.LastSearch);
end.

Вроде бы и мелочь но при работе с большими списками(~10 000 элементов) разница хорошо заметна.

function IsBadNomber(var i:integer):boolean;
begin
  if i = 5 then
  begin
    i := 0;
    Result := true;
  end;
end;

begin
  writeln(IsBadNomber(5));
end.

Данный объект не может быть передан как var-параметр

Иногда надо только получить результат функции с var параметром, в таком случае придётся сделать 1 бесполезную переменную или писать ещё 1 функцию, можете разрешить такую запись? Или если это поведение наследованное от C и нельзя изменить - разрешить описывать 2 функции function IsBadNomber(var i:integer):boolean; и function IsBadNomber(i:integer):boolean;, потому что сейчас они считаются одинаковыми.

В качестве параметра-переменной можно передавать только переменные

Ну а что насчёт разрешить описывать такие функции в 1 модуле? function IsBadNomber(var i:integer):boolean; function IsBadNomber(i:integer):boolean; ?

Нет. Выбрать между ними для IsBadNomber(n) невозможно

Дайте функции другое имя и не переживайте

Здравствуйте! При попытке (точнее после) удалить модуль PABCSystem.pcu (и pas), возникла ошибка компиляции. При этом ни один тип, класс, запись или метод из него не использовался! Т. е. писал я как на C#: {$Reference ‘System.dll’} {$AppType Console} Uses System; Begin System.Console.WriteLine(‘Hello, World!’); End. Возможно ли как-то отключить модуль? Просто объём одной и той-же программы, откомпилированной на Паскале во много раз больше, чем на C# (3 кб для C# против 20 для Паскаля). Да и просто хотелось бы более чистого кода.

2 лайка

Нет, невозможно. 20 Кб - это очень мало по сегодняшним меркам.

20 Kb было много, когда писали в ассемблере коды для ПЗУ объемом 32К. Тогда от кода требовались эффективность и компактность. Появление бутстрэппинга и, в особенности, ООП привело к вырождению понятий эффективности и компактности. Даже на IBM \360 \370 (ЕС ЭВМ) компилятор полноценного Fortran-77 выполнялся при запросе памяти 64К.

1 лайк

Ну этим едва ли можно гордиться. Из-за нехватки ресурсов городили костыль на костыле. А ООП и эффективность перпендикулярны. В ООП тоже вызываются функции, только иногда через таблицу виртуальных методов.

Я бы не стал так утверждать. Дело не в парадигме ООП, а в том, что его использование “подталкивает” к написанию неэффективного кода". Из-за “матрешки”, порождаемой цепочкой наследований, неэффективный код предков имеет тенденцию размножаться в потомках. Это не вина ООП, это следствие “кривых ручек”. Но при программировании в эпоху “до ООП” размножения в таких объемах не было.

Иногда эти 20кБ, при разработке серьёзных проектов, могут быть решающими. Проблема размера файла (и используемых ресурсов тоже) находится в неиспользуемых классах, методах, переменных. В случае Паскаля, это всё (“На любой случай жизни”) лежит в модуле (что самое печальное - в системном, неотключаемом), большинство возможностей которого может быть просто не нужно в данном случае, но при компиляции в код копируется всё, без каких либо исключений. А учитывая возможности платформы, необходимость такого модуля вызывает сомнения. Во многих .NET-языках внутренние стандартные модули фактически исчезли за ненадобностью (например, C++ и C#).

1 лайк

Где оно может быть решающим, остается загадкой. Серьезные проекты они большие. Там эти 20Кб сущая ерунда, которой можно пренебречь.

1 лайк

Кстати, а разве компилятор С не отрубает все функции которые не используются?