Pascal 编程/入门
在本章中,你将学习
- Pascal 源代码文件的结构
- 基本术语
所有编程任务都需要一个源代码文件,在 Pascal 中称为 program
。一个 program
源代码文件由编译器翻译成可执行应用程序,你可以运行它。让我们看看一个最小的 program
源代码文件
program nop;
begin
{ intentionally empty }
end.
- 第一行
program nop;
表示该文件是 Pascal 程序的源代码文件。 begin
和end
标记一个框架。在接下来的内容中,我们将详细解释这一点。{ intentionally empty }
是一个 注释。注释将被编译器忽略,因此不会以任何方式影响可执行程序的外观或行为。- 最后一个点
.
在最后一个end
后告诉编译器程序源代码文件的结束位置。
如果你觉得这本书的节奏让你难以理解,维基教科书 编程基础 可能更适合你。 |
为了启动你的程序,你需要编译它。
首先,复制上面显示的程序。我们建议你实际输入这些示例,而不是复制粘贴代码。将文件命名为 nop.pas
。 nop
是程序的名称,文件扩展名 .pas
帮助你识别 源代码 文件。
完成后,告诉编译器你已经选择编译程序了
fpc
,后跟一个指向源代码文件的(相对或绝对)文件名路径fpc nop.pas
Target OS: Linux for x86-64
Compiling nop.pas
Linking nop
4 lines compiled, 0.1 sec
nop
的新文件。这是你可以启动的可执行程序。
gpc
,后跟一个指向源代码文件的(相对或绝对)文件名路径gpc nop.pas
gpc
不会报告任何错误,但将会有一个(默认情况下)名为 a.out
的新文件。
最后,你可以通过你的 OS 提供的其中一种方法来执行程序。例如,在控制台中,你只需输入可执行文件的名称:./nop
(其中 ./
指的是 Unix 类环境中的当前工作目录)。由于此程序(有意地)没有做任何事情,你不会注意到任何(明显的)变化。毕竟,程序名称 nop
是 无操作 的缩写。
程序需要为每个平台编译。 平台 指的是 OS、OS 版本以及使用的微处理器体系结构和制造。只有当所有这些指标都匹配时,你才能将可执行文件复制到另一台计算机并运行它。否则,它可能会失败。现代 OSs 可以阻止你运行不兼容的程序(在一定程度上)。 |
恭喜你编写了第一个 Pascal 程序!公平地说,这个程序没什么用处,对吧?作为一个小步骤,让我们让计算机说话(比喻地)并向世界介绍自己
program helloWorld(output);
begin
writeLn('Hello world!');
end.
你会注意到第一个区别在第一行。不仅程序名称发生了变化,而且还有 (output)
。这是一个程序 参数。实际上,它是一个列表。在这里,它只包含一项,但一般形式是 (a, b, c, d, e, …)
等等。程序参数指定了 OS 需要向程序提供的一个外部实体,以便程序能够按预期运行。我们将在后面详细介绍,但现在我们需要知道有两个 特殊 程序参数:input
和 output
。这些参数象征着与 OS 交互的默认方式。通常,如果你在控制台中运行程序,output
是控制台的显示。
下一个区别是 writeLn('Hello world!')
。这是一个语句。语句是一个例程调用。例程名为 writeLn
。 WriteLn
有(可选)参数。参数是,同样,以逗号分隔的列表,用括号括起来。
例程
[edit | edit source]例程是可重用的代码片段,可以反复使用。例程 writeLn
,缩写为 write line,将所有提供的参数写入目标,然后是一个“换行符”(一些使光标移动到下一行的魔法)。然而,这里目标是不可见的。这是因为它是可选的,可以省略。如果省略,目标将变为 output
,因此我们的控制台输出。如果我们想要明确命名目标,我们必须写 writeLn(output, 'Hello world!')
。 WriteLn(output, 'Hello world!')
和 writeLn('Hello world!')
是完全相同的。缺少的可选参数将自动插入,但它减轻了程序员的输入负担。
为了使用一个例程,我们写它的名称,作为一个语句,后面跟着参数列表。我们在上面第 2 行做了这件事。
例程需要在使用之前定义。 然而,例程 |
字符串字面量
[edit | edit source]参数 'Hello world!'
是一个所谓的字符串字面量。字面量意味着,你的程序将按原样使用这个字符序列,不会以任何方式解释它,并将它传递给例程。一个 string
字面量由打字机(直线)撇号分隔。
保留字
[edit | edit source]与之相反,单词 program
、begin
和 end
(以及你在代码示例中以粗体显示的许多其他单词)是所谓的保留字。它们传达了关于如何解释和构建可执行程序的特殊含义。你只能在特定的地方写它们。
但是,你可以写 string 字面量 'program' 。字符串分隔符“禁用”了解释。 |
行为
[edit | edit source]helloWorld.pas
,复制源代码(通过手动输入),编译并运行它
program helloWorld(output);
begin
writeLn('Hello world!');
end.
Hello world!
Hello world!
,没有直引号,在一个单独的行上。这不是很棒吗?program helloWorld(input, output);
begin
writeLn('Hello world!');
readLn();
end.
readLn()
将使你的程序停顿,因此程序不被认为是完成的。在你按下 ↵ Enter 后,终端窗口应该再次关闭。顺便说一下,这种类型的程序是“Hello world”程序类别的一个例子。它们用于演示任何编程语言的源代码文件需要满足的最低要求。更多示例请参见 WikiBook“计算机编程”中的 Hello world(并欣赏 Pascal 与其他编程语言相比的简单性)。
注释
[edit | edit source]我们已经看到了写注释的选项。注释的目的是作为程序员的提醒。
注释语法
[edit | edit source]Pascal 将大括号定义为注释分隔符:{ comment }
(空格用于视觉引导,没有意义)。左大括号打开或开始注释,右大括号关闭注释。
在注释“内部”,你不能使用注释结束符作为文本的一部分。第一个出现的正确结束符将是注释的结束。 |
然而,当 Pascal 被开发时,并非所有计算机系统都拥有键盘上的大括号。因此,使用括号和星号的双字母组合也变得合法:(* comment *)
。
这样的注释被称为块注释。它们可以跨越多行。Delphi 引入了另一种注释风格,行注释。它们以两个斜杠 //
开始,包含当前行结束之前的所有内容。
Delphi、FPC 以及 GPC 都支持所有三种注释风格。
有用的注释
[edit | edit source]写好的注释是一种“艺术”。
注释不应重复可以从源代码本身推断出来的内容。 program helloWorld(output);
begin { This is where the program begins }
writeLn('Hello world!');
end. (* This is where the program ends. *)
|
注释应该解释不明显的信息program nop;
begin
{ intentionally empty }
end.
|
|
写注释时,坚持使用一种自然语言。在接下来的章节中,你将看到许多“好的”注释(除非它们清楚地展示了以下内容)。
术语
[edit | edit source]熟悉以下术语(即右侧以注释形式打印的术语)
program demo(input, output); // program header
// ───────────────────────────────────┐
const // ────────────────────┐ │
answer = 42; // constant definition ┝ const-section│
// ────────────────────┘ │
type // ────────────────────┐ │
employee = record // ─┐ │ │
number: integer; // │ │ │
firstName: string; // ┝ type definition │ │
lastName: string; // │ ┝ type-section │
end; // ─┘ │ │
// │ │
employeeReference = ^employee; // another type def. │ │
// ────────────────────┘ ┝ block
// │
var // ────────────────────┐ │
boss: employeeReference; // variable declaration┝ var-section │
// ────────────────────┘ │
// │
begin // ────────────────────┐ │
boss := nil; // statement │ │
writeLn('No boss yet.'); // another statement ┝ sequence │
readLn(); // another statement │ │
end. // ────────────────────┘ │
// ───────────────────────────────────┘
请注意,每个常量和类型定义,以及每个变量声明都进入专门的部分。保留字 const
、type
和 var
充当标题。
一个序列也称为复合语句。定义、声明和序列的组合称为块。定义和声明是可选的,但序列是必需的。序列可以为空,正如我们在上面已经证明的那样,但这通常不是这种情况。
不用担心,定义和声明之间的区别将在后面解释。现在你应该知道和认识节和块。
program commentDemo;
begin
{ (* Hello { { { }
(* (* { (* Foo }
{ (* Bar *)
第一个注释结束字符标记整个注释的结束,无论它以{
还是(*
开头。这意味着,这里编译器会报错
{ start (* again? } *)
行注释不受此影响,因为它们没有显式的结束分隔符。这将编译通过,不会报错
// *) } { (*
end.
writeLn
(注意缺少参数列表)的作用是什么?WriteLn
在没有提供任何参数的情况下,会将一个空行打印到默认目标,即output
。
program
,演示这一点(或类似的功能) #### ####
######## ########
## ##### ##
## # ##
## ILY ##
## sweetie ##
### ###
### ###
### ###
###
#
program valentine(output);
begin
writeLn(' #### ####');
writeLn(' ######## ########');
writeLn(' ## ##### ##');
writeLn(' ## # ##');
writeLn(' ## ILY ##');
writeLn(' ## sweetie ##');
writeLn(' ### ###');
writeLn(' ### ###');
writeLn(' ### ###');
writeLn(' ###');
writeLn(' #');
end.
注意,程序参数列表(第一行)只列出了output
。注意,虽然代码中的空格数量无关紧要,但它们在字符串文字中很重要。