Fungsi, prosedur dan tipe primitif dasar

Измените файл 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(значение) позволяет указать возвращаемое значение и досрочно завершить функцию
  • Функции можно вызывать без сохранения возвращаемого значения, подходит для логики с побочными эффектами, например изменение глобальных переменных

Правила возвращаемых значений функций

  1. Встроенная специальная переменная Result хранит возвращаемое функцией значение, читается и записывается как обычная локальная переменная
function MyFunction(const S: string): string;
begin
  Result := S + 'One';
  Result := Result + 'Two';
end;
Code language: PHP (php)
  1. Старый синтаксис позволяет присваивать значение напрямую имени функции (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 разница:

  1. SumIntegersUntilZero()вызвать функцию рекурсивно и получить возвращаемое значение
  2. SumIntegersUntilZero → обратиться к внутренней переменной Result (собственное возвращаемое значение функции)

Код без скобок:

Result := Result + SumIntegersUntilZero;

Компилятор интерпретирует как:

Result := Result + Result;

Эквивалентно Result := Result * 2, вся логика рекурсии ломается, появляется бесконечный цикл с постоянно удваивающимися числами.

В данном примере функция вызывает саму себя, пока вводимое число не станет нулём; при любом ненулевом значении рекурсия продолжается.

Exit — досрочный выход из функции

  1. Exit без параметров: немедленно выйти из функции, вернуть уже присвоенное значение Result
  2. 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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *