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。注意,雖然程式碼中的空格數量無關緊要,但它們在字串文字中很重要。
