修改上节课的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);
// Division using "/" always makes float result, use "div" for integer division
X := 15 / 5;
WriteLn('X is now: ', X); // scientific notation
WriteLn('X is now: ', X:1:2); // 2 decimal places
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 lines compiled, 0.0 sec, 39248 bytes code, 2484 bytes data
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); // 限定保留2位小数
end. //末尾是 end.(带点),代表整个程序结束;Code language: Delphi (delphi)
函数和过程有一个begin 和end ,表示函数体的开始和结束,类似C C++ JAVA等语言的 { 和 }
WriteLn是往控制台中输出内容,‘ ’表示字符串,WriteLn(‘A + 10 =:’, A + 10);会依次输出字符串 A + 10 =:和后面的表达式的结果A + 10
整个程序只能有 1 个最外层 begin和end. 里面就是程序的代码,里面再去调用其他的函数和过程
X := 15 / 5;
WriteLn(‘X is now: ‘, X); // scientific notation
WriteLn(‘X is now: ‘, X:1:2); // 2 decimal places
/是浮点数除法,商也是浮点数,
前面两行是预编译命令
{$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}:指定程序为控制台程序(弹出黑窗口,而非窗口 GUI 程序) 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,完全失去递归逻辑,无限循环且数值疯狂翻倍。
本例子,然函数不断递归调用,直接到输入为0才退出函数。只要不为零就递归调用本身。
Exit 提前退出
- 无参 Exit:直接退出,返回当前已赋值的 Result
Exit(值):直接指定返回值并结束函数,等效 C 语言 return x
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); // 副作用:全局变量自增
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)内置标准函数,作用是变量自增 1。
var 是 Pascal 的变量声明关键字,作用:定义变量。
var
Count, MyCount: Integer;Code language: JavaScript (javascript)
var:开启变量声明区
Count, MyCount:两个变量名
Integer:整数类型
上面例子,var里面的,全局变量,整个程序所有过程、函数都能用