Измените файл dpr из предыдущего урока на следующий код
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
program MyProgram;
procedure MyProcedure(const A: Integer);
begin
WriteLn('A + 10 is: ', A + 10);
end;
function MyFunction(const S: string): string;
begin
Result := S + 'strings are automatically managed';
end;
var
X: Single;
begin
WriteLn(MyFunction('Note: '));
MyProcedure(5);
// Деление через "/" всегда даёт дробное число, для целого деления используйте "div"
X := 15 / 5;
WriteLn('X is now: ', X); // научная нотация
WriteLn('X is now: ', X:1:2); // 2 знака после запятой
end.Code language: PHP (php)
D:\fpcdemo>fpc mydemo.dpr
Free Pascal Compiler version 3.2.2 [2021/05/15] for i386
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Win32 for i386
Compiling mydemo.dpr
Linking mydemo.exe
20 строк скомпилировано, 0,0 сек, 39248 байт кода, 2484 байт данных
D:\fpcdemo>mydemo
Note: strings are automatically managed
A + 10 is: 15
X is now: 3.000000000E+00
X is now: 3.00
D:\fpcdemo>Code language: CSS (css)

Ниже построчное объяснение комментариев. Неанглийские символы могут отображаться искажённо; настроите консоль для корректного вывода китайских символов.
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
program MyProgram;
// Пользовательское имя программы. Консольная программа Pascal начинается с program имя;, затем объявляются переменные, процедуры и основной код
// Без возвращаемого значения: procedure процедура. Процедуры и функции выполняются только при вызове
procedure MyProcedure(const A: Integer);
begin
WriteLn('A + 10 =:', A + 10);
end;
// С возвращаемым значением: function функция
function MyFunction(const S: string): string;
begin
Result := S + 'память строк управляется системой автоматически';
end;
// В Object Pascal нет функции main, самый внешний блок begin...end. является точкой входа в программу, это основной блок кода
var
X: Single; // Базовый тип одинарной точности с плавающей точкой
begin
// Всю исполняемую логику пишем здесь
WriteLn(MyFunction('Подсказка:'));
MyProcedure(5);
// Оператор "/" всегда выдаёт дробное число, для целого деления используем div
X := 15 / 5;
WriteLn('X is now:', X); // Автоматический вывод в научной нотации
WriteLn('X is now:', X:1:2); // Ограничение двумя знаками после запятой
end. // end. с точкой обозначает полное завершение программыCode language: PHP (php)
Каждая функция и процедура имеют пару begin и end для обозначения начала и конца тела, аналог фигурных скобок { } в C, C++, Java и других языках.
WriteLn выводит текст в консоль, одинарные кавычки ‘ ‘ обрамляют строковые литералы. WriteLn('A + 10 =:', A + 10); последовательно выводит строку A + 10 =: и результат вычисления A + 10.
В программе может быть только один самый внешний блок begin и end., внутри которого находится основной код, вызывающий другие функции и процедуры.
X := 15 / 5;
WriteLn(‘X is now: ‘, X); // научная нотация
WriteLn(‘X is now: ‘, X:1:2); // два знака после запятой
/ — оператор деления с плавающей точкой, частное всегда является дробным числом.
Первые две строки — директивы предварительной компиляции
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}Code language: PHP (php)
Это специфическая для FPC условная директива компиляции
{$ifdef FPC}: Промежуточные настройки выполняются только если компилятор — Free Pascal{$mode objfpc}: Переключение в синтаксический режим ObjFpc{$H+}: Включить длинные строки (современный тип string с автоматическим управлением памятью, обязательно){$J-}: Отключить изменяемые константы (константы нельзя менять во время выполнения, повышает безопасность){$endif}: Конец условного блока
Назначение: Включать современный синтаксис только при компиляции через FPC; компилятор Delphi пропускает весь этот блок.
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}Code language: PHP (php)
Мультиплатформенная условная компиляция
MSWINDOWS: Действует только под операционной системой Windows{$apptype CONSOLE}: Определяет программу как консольное приложение (открывается чёрное терминальное окно вместо графического окна). При компиляции под Linux/macOS эта строка игнорируется.
Основные ключевые знания
string— нативный базовый тип; FPC/Delphi управляет памятью автоматически, ручная очистка не требуется- procedure процедура: без возвращаемого значения; function функция: с возвращаемым значением, хранится во встроенной переменной
Result - Разделение операторов деления:
/деление с плавающей точкой;divцелочисленное деление с отбрасыванием дробной части - Форматированный вывод
переменная:общаяШирина:знакиПослеЗапятойдля контроля отображения дробных чисел - Безпараметрические рекурсивные функции требуют пустых скобок
()для устранения синтаксической неоднозначности Exit(значение)позволяет указать возвращаемое значение и досрочно завершить функцию- Функции можно вызывать без сохранения возвращаемого значения, подходит для логики с побочными эффектами, например изменение глобальных переменных
Правила возвращаемых значений функций
- Встроенная специальная переменная
Resultхранит возвращаемое функцией значение, читается и записывается как обычная локальная переменная
function MyFunction(const S: string): string;
begin
Result := S + 'One';
Result := Result + 'Two';
end;
Code language: PHP (php)
- Старый синтаксис позволяет присваивать значение напрямую имени функции (
MyFunction := xxx), не рекомендуется из-за плохой читаемости; используйте единообразноResult.
C/C++/Java/C# используют
=для присваивания и==для сравнения равенства. Pascal работает наоборот::=для присваивания переменных, одиночный=для сравнения, совпадает с математической нотацией.В Pascal оператора
==нет
Замените старую MyFunction из примера на эту версию. Данная функция добавляет сначала строку «One», затем «Two» в конец переданной при вызове строки.
Итоговая возвращаемая строка: исходная строка + One + Two
Рекурсивные вызовы
Безпараметрические функции при рекурсивном вызове должны иметь пустые скобки (), чтобы различить «вызвать функцию» и «прочитать текущее возвращаемое значение»:
function SumIntegersUntilZero: Integer;
var I: Integer;
begin
ReadLn(I);
Result := I;
if I <> 0 then
Result := Result + SumIntegersUntilZero(); // рекурсивный вызов с ()
end;
Code language: JavaScript (javascript)
Для безпараметрической функции SumIntegersUntilZero разница:
SumIntegersUntilZero()→ вызвать функцию рекурсивно и получить возвращаемое значениеSumIntegersUntilZero→ обратиться к внутренней переменнойResult(собственное возвращаемое значение функции)
Код без скобок:
Result := Result + SumIntegersUntilZero;
Компилятор интерпретирует как:
Result := Result + Result;
Эквивалентно Result := Result * 2, вся логика рекурсии ломается, появляется бесконечный цикл с постоянно удваивающимися числами.
В данном примере функция вызывает саму себя, пока вводимое число не станет нулём; при любом ненулевом значении рекурсия продолжается.
Exit — досрочный выход из функции
- Exit без параметров: немедленно выйти из функции, вернуть уже присвоенное значение Result
Exit(значение): сразу указать возвращаемое значение и завершить функцию, аналог return x в языке C
function AddName(const ExistingNames, NewName: string): string;
begin
if ExistingNames = '' then
Exit(NewName); // сразу вернуть NewName и остановить выполнение
Result := ExistingNames + ', ' + NewName;
end;
Code language: PHP (php)
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
program MyProgram;
procedure MyProcedure(const A: Integer);
begin
WriteLn('A + 10 is: ', A + 10);
end;
function AddName(const ExistingNames, NewName: string): string;
begin
if ExistingNames = '' then
Exit(NewName);
Result := ExistingNames + ', ' + NewName;
end;
var
X: Single;
begin
WriteLn(AddName('Tom','Jack'));
WriteLn(AddName('Tom',''));
WriteLn(AddName('','Jack'));
end.Code language: PHP (php)
Вызов функции как процедуры (игнорировать возвращаемое значение)
Даже если функция возвращает значение, её можно запустить только для выполнения логики, игнорируя результат; удобно для кода с побочными эффектами (изменение глобальных переменных):
var
Count, MyCount: Integer;
function CountMe: Integer;
begin
Inc(Count); // побочный эффект: увеличить глобальную переменную на 1
Result := Count;
end;
begin
Count := 10;
CountMe; // игнорируем возврат, только выполняем действие, Count становится 11
MyCount := CountMe; // сохраняем возвращаемое значение, Count становится 12
end.
Code language: PHP (php)
Полный рабочий пример
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
program MyProgram;
var
Count, MyCount: Integer;
function CountMe: Integer;
begin
Inc(Count);
Result := Count;
end;
begin
Count := 10;
WriteLn(CountMe);
MyCount := CountMe;
WriteLn(MyCount);
end.Code language: PHP (php)
Inc — встроенная стандартная функция Pascal (FPC/Delphi), увеличивает переменную на единицу.
var — ключевое слово объявления переменных в Pascal, предназначено для определения переменных.
var
Count, MyCount: Integer;Code language: JavaScript (javascript)
var: открывает блок объявления переменных
Count, MyCount: два имени переменных
Integer: целочисленный тип данных
Переменные, объявленные в блоке var этого примера — глобальные, доступны всем процедурам и функциям всей программы.
Fungsi, prosedur dan tipe primitif dasar