Программы на Паскале компилируются на сервере с помощью 32-битного компилятора FreePascal 2.6.4. Он настроен в режиме совместимости с Borland Delphi и запускается со следующими параметрами:
ppc386 %1 -WC -Ci-o-r-t- -Xs -Sdgich -Se10 -l- -vwnh -n -dONLINE_JUDGE
Вы можете скачать FreePascal и прочитать online документацию на сайте www.freepascal.org.
Пример решения задачи
Вот пример решения задачи A + B на Паскале:
var
a, b: integer;
begin
readln(a, b);
writeln(a + b);
end.
Что нового в 32-битном компиляторе по сравнению с 16-битным
Если вы привыкли писать программы в старых 16-битных компиляторах для DOS, например, в Borland Pascal 7.0, то вам будет полезно знать следующее:
- Можно использовать массивы размером более 64 КБ.
- Тип
integer
является 32-битным и совпадает с типом longint
. 16-битный целый знаковый тип называется smallint
.
- Строки теперь не ограничены 255 символами. Не следует обращаться к нулевому символу, чтобы узнать длину строки, используйте для этого функцию
length(s)
. Установить длину строки можно при помощи процедуры setlength(s, n)
.
Кроме того, появилось много новых ключевых слов. Следующие слова не могут быть переопределены или использованы как идентификаторы:
as false new
class finalization on
dispose finally property
except initialization raise
exit is true
exports library try
В дополнение к указанным выше, слова protected
и published
стали зарезервированными внутри описания объекта. Также имя result
в теле функции зарезервировано: значением соответствующей переменной является результат работы функции, и объявление второго такого имени приведёт к ошибке компиляции. Например, следующие определения функций эквивалентны:
function Sum(a, b: integer): integer;
begin
Sum := a + b;
end;
function Sum(a, b: integer): integer;
begin
result := a + b;
end;
А вот такой код не скомпилируется:
function Sum(a, b: integer): integer;
var
result: integer;
begin
result := a + b;
Sum := result;
end;
Особенности компилятора по сравнению с другими 32-битными компиляторами Паскаля
Есть некоторые особенности компилятора, используемого на сервере, которые полезно знать.
- На сервере нет модулей
crt
и wincrt
, так как процедуры, содержащиеся в них, не нужны для решения задач. - При динамическом выделении памяти размер блока округляется до кратного 16 байтам. Например, если вы выделяете много блоков по 4 байта, то ваша программа будет использовать в 4 раза больше памяти, чем надо. Пользуйтесь статическими структурами данных, они лишены этого недостатка и, как правило, работают быстрее динамических.
- Множества могут занимать лишь 4 или 32 байта, что также может привести к значительному перерасходу памяти. Часто хорошей альтернативой множествам оказывается использование битов целого числа (или массива целых чисел).
- Нельзя явно приводить типы переменных целочисленного типа и типа с плавающей точкой. Выражение «
x := extended(i)
», где x
имеет тип extended
, а i
— integer
, является ошибочным. Тогда как выражение «x := i
» — правильное.
Нельзя менять значение переменной цикла for
внутри цикла. Следующий код не скомпилируется:
for i := 1 to 10 do
begin
if i mod 2 = 0 then inc(i);
writeln(i);
end;
Более того, после цикла for
значение переменной цикла не определено. Т.е. ее значение нельзя использовать, например, в целях поиска. Следующий пример сработает по-разному на разных компиляторах:
var
a: array[1..10] of integer;
i: integer;
begin
for i:=1 to 10 do
a[i] := i*i;
for i:=1 to 10 do
if a[i] = 17 then break;
writeln('i = ', i);
end.
{
Delphi output: i = 11
FreePascal output: i = 10
}
Как пользоваться 64-битными целыми типами данных
Компилятор полностью поддерживает 64-битные целые, как со знаком, так и без знака. 64-битное целое со знаком имеет диапазон значений от –9223372036854775808 до 9223372036854775807, без знака — от 0 до 18446744073709551615. Знаковый тип назывется int64
, беззнаковый — qword
. Следующий пример иллюстрирует использование 64-битных целых типов:
var
a: int64;
b: qword;
begin
read(a);
read(b);
writeln(a);
writeln(b);
end.
Как считать данные до конца входного потока
Для решения некоторых задач требуется уметь читать входные данные до конца входного потока. Следующие примеры показывают, как можно организовать ввод до конца входного потока в случаях, если входные данные состоят из чисел, из строк или из отдельных символов.
{numbers}
var n: integer;
...
while not seekeof do
begin
read(n);
...
end;
{lines}
var line: string;
...
while not eof do
begin
readln(line);
...
end;
{characters}
var c: char;
...
while not eof do
begin
read(с);
...
end;
Прочие замечания
Иногда вердикт Wrong Answer на самом деле означает Runtime error. Это связано с тем, что FreePascal самостоятельно перехватывает некоторые ошибки выполнения программ и выводит сообщение в выходной поток.
Для того, чтобы увеличить объем стека и избежать его переполнения при использовании «глубокой» рекурсии, следует использовать специальную директиву (в примере размер стека устанавливается равным 16 МБ):
{$M 16777216}
Удобно использовать для отладки решений условную директиву ONLINE_JUDGE
:
var
a, b: longint;
begin
{$IFNDEF ONLINE_JUDGE}
assign(input, 'input.txt');
reset(input);
assign(output, 'output.txt');
rewrite(output);
{$ENDIF}
readln(a, b);
writeln(a + b);
{$IFNDEF ONLINE_JUDGE}
close(input);
close(output);
{$ENDIF}
end.
Такая программа на вашем компьютере будет читать данные из файла input.txt
и выводить результат в файл output.txt
. На сервере же она будет пользоваться стандартными входным и выходным потоками.
Прежние компиляторы
- FreePascal 1.0.6 использовался до 8 августа 2005 года.
- FreePascal 2.0.1 использовался до 4 января 2006 года.
- FreePascal 2.0.2 использовался до 24 октября 2006 года.
- FreePascal 2.0.4 использовался до 3 октября 2014 года.