CHAPTER C++ - 碁峰資訊epaper.gotop.com.tw/pdf/ACL018800.pdf · 2-2 2.1 CPU C++ !"#$%&'() 1. *...

9
2

Transcript of CHAPTER C++ - 碁峰資訊epaper.gotop.com.tw/pdf/ACL018800.pdf · 2-2 2.1 CPU C++ !"#$%&'() 1. *...

Page 1: CHAPTER C++ - 碁峰資訊epaper.gotop.com.tw/pdf/ACL018800.pdf · 2-2 2.1 CPU C++ !"#$%&'() 1. * (edit) 2. +,- (preprocess) 3. (compile) 4. ./ (link) 5. 01 (load)

C H A P T E R

2

C++ 的基本語法和使用環境

子曰:「可與言,而不與之言,失人﹔

不可與言,而與之言,失言。

君子不失人,亦不失言。」

《論語﹒衛靈公第十五》

親自撰寫和執行程式是學好程式語言的不二法門。本章藉由兩個簡單的程式,介

紹 C++ 程式的基本結構和開發環境,讓初學者能逐漸建立使用 C++ 的信心。

2.1 基本程式開發步驟

2.2 第一個完整的 C++ 程式

2.3 Borland C++ 編譯器的取得和安裝使用

2.4 Visual C++.NET 程式開發步驟

2.5 第二個 C++ 程式

2.6 C++ 代號的命名規則

2.7 本章重點

2.8 本章練習

Page 2: CHAPTER C++ - 碁峰資訊epaper.gotop.com.tw/pdf/ACL018800.pdf · 2-2 2.1 CPU C++ !"#$%&'() 1. * (edit) 2. +,- (preprocess) 3. (compile) 4. ./ (link) 5. 01 (load)

� 2-2

2.1 基本程式開發步驟

因為 CPU 只能執行機器碼,因此所有的高階程式語言都需要經過編譯才

能夠執行。C++ 程式的開發包括下列六個步驟:

1. 編輯 (edit)

2. 前處理 (preprocess)

3. 編譯 (compile)

4. 聯結 (link)

5. 裝載 (load)

6. 執行 (execute)

所以一個完整的程式開發環境必需包括編輯器 (editor)、前處理器

(preprocessor)、編譯器 (compiler)、聯結器 (linker) 和裝載器 (loader) 等軟

體工具,以及提供含有標準程式庫 (the Standard C++ Library) 和 MFC (微軟

基礎類別, the Microsoft Foundation Classes) 等現成軟體元件的程式庫。

程式的編輯

開發程式的一開始,我們必需藉由編輯器 (editor) 來完成程式原始文字

檔案的撰寫。撰寫完成的含有 C++ 文字指令之程式檔案稱為原始程式碼

(source code)。編輯結果通常存放於硬碟、磁碟片、CD-R,或 CD-RW 中,C++

的原始檔案通常有 .cpp 的延伸檔名 (extension)。在 UNIX 系統下,我們有

emacs 和 vi 兩種編輯器可以選用,而在個人電腦 Windows 作業系統下可用的

編輯器種類更多。如果我們使用 Microsoft Visual C++ 或 Borland C++ Builder

等完整的開發環境,則其中已經包括有專用的編輯器,這類的專用編輯器和

其它部份有較緊密的銜接關係。

程式的編譯

其次,要使用編譯器 (compiler) 將程式轉譯成機器碼,稱為目的程式碼

(object code)。在執行編譯前,有一個叫做前處理器 (preprocessor) 的程式會

Page 3: CHAPTER C++ - 碁峰資訊epaper.gotop.com.tw/pdf/ACL018800.pdf · 2-2 2.1 CPU C++ !"#$%&'() 1. * (edit) 2. +,- (preprocess) 3. (compile) 4. ./ (link) 5. 01 (load)

第二章 C++ 的基本語法和使用環境

2-3 �

自動被叫用執行,它依照程式內的前處理指令 (preprocessor directives) 進行

編譯前的特定處理;包括將稱為標頭檔 (header file) 的文字檔案放入原始程

式碼中,以及在原始程式中取代某些特定的文字等動作。在以下的各章中,我

們會零星的介紹常用的前處理指令,較完整的說明則放在第十一章裏面。

編譯器 (compiler) 的功能在於將前處理器產生的中間檔 (又稱為轉譯單

元,translation unit) 轉譯成二進位機器碼,稱為目的檔 (object file)。並同時

進行語法檢查和程式碼最佳化的動作。為了簡化編譯器的設計工作,某些系

統的編譯器所產生的檔案是我們能夠閱讀的組合語言程式碼 (assembly

code),其後再自動呼叫組合器 (assembler) 產生目的程式碼。目的檔中各個

指令和資料被編譯器設定的位置只是相對位址 (relative address),還不是絕對

位址 (absolute address)。

最後的編譯階段稱為聯結 (linking)。程式多少都會引用一些不是自己撰

寫,而且已經編譯成機器碼的程式片段,例如內建的或自行開發的程式庫。

聯結器 (linker) 的工作是將目的檔與在程式中指定的這些機器碼檔案聯結成

完整的執行檔 (executable file)。此外,聯結器還進行了將位址從相對位址轉

換為絕對位址的工作。

以 UNIX 作業系統為例,要針對一個稱為 test.C 的原始檔案完成上述前

處理、編譯,和聯結的整個過程,只要在命令提示列 (command line) 的提示

符號 (prompt) 後輸入

cc test.C

再按下輸入鍵 (亦即 Enter 鍵) 即可。如果沒有錯誤,就可以成功編譯,而得

到一個稱為 a.out 的執行檔。

如果是使用 2.4節即將介紹的 Borland C++ Compiler,則對於檔案 Test.cpp

的編譯只要在 DOS 的命令提示符號後鍵入

bcc32 test

再按輸入鍵 (Enter) 即可。成功的編譯會在顯示器上顯示以下的輸出訊息:

Page 4: CHAPTER C++ - 碁峰資訊epaper.gotop.com.tw/pdf/ACL018800.pdf · 2-2 2.1 CPU C++ !"#$%&'() 1. * (edit) 2. +,- (preprocess) 3. (compile) 4. ./ (link) 5. 01 (load)

� 2-4

Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland

Test.CPP:

Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland

並在原檔案所在的資料夾內產生 Test.obj,Test.tds,和 Test.exe 三個檔案。其

中 Test.exe 就是我們要的執行檔。

也就是說,不管在 UNIX,DOS,還是 Windows 作業系統中操作,前處

理器和聯結器的動作都隱藏在單一的編譯指令之下。除非因為指令錯誤或找

不到指定的聯結檔案和程式庫,使用者通常察覺不到這兩個程式的存在。

程式的裝載和執行

在程式執行前,需要裝載器 (loader) 的協助把可執行碼 (executable

code,例如上述的 a.out 和 Test.exe) 放置於主記憶體內。在某些情況下,這

個裝載的動作包括動態聯結檔 (DLL,Dynamically Linked Libraries,具有副

檔名 .dll) 的加入。

上述的過程可以畫成圖 2.1.1 的步驟示意圖:

執行結果

目的檔

執行檔

聯結器

裝載器

程式庫

轉譯單元 前處理器 編譯器

標頭檔

原始程式碼

概念

編輯器

圖 2.1.1 C++ 程式開發的步驟

Page 5: CHAPTER C++ - 碁峰資訊epaper.gotop.com.tw/pdf/ACL018800.pdf · 2-2 2.1 CPU C++ !"#$%&'() 1. * (edit) 2. +,- (preprocess) 3. (compile) 4. ./ (link) 5. 01 (load)

第二章 C++ 的基本語法和使用環境

2-5 �

DLL 是一個新的技術,可以把執行檔切割成許多小檔案,以便於選擇性的在

執行時聯結特定的執行檔,避免過於龐大的單一執行檔。在有昇級或修正需要

時,也只要取代部份執行檔就可以。

要進行程式的裝載和執行也很單純,沿用上述的例子,在 UNIX 下輸入

的指令是

a.out

在 DOS 下則只要輸入

test.exe

test

再按輸入鍵即可。如果要把原本會在顯示器上顯示的結果存到一個稱為

Result.txt 的檔案內,在 DOS 下也只需要在裝載和執行時,同時在執行檔名

稱後面加上符號「>」,再加上檔案名稱就可以。例如:

test > Result.txt

2.2 第一個完整的 C++ 程式

C++ 的語法對於第一次接觸這個程式語言的人會顯得有些奇特。我們要

在本節中介紹一個非常簡單,但是可以凸顥 C++ 語法特性和程式組織的程

式。這個程式經過編譯後,執行時能在顯示器上顯示一行文字。

以下是程式的全貌:

// Test.cpp

// 程式的目的是在顯示器上顯示一行文字

#include <iostream>

using std::cout;

Page 6: CHAPTER C++ - 碁峰資訊epaper.gotop.com.tw/pdf/ACL018800.pdf · 2-2 2.1 CPU C++ !"#$%&'() 1. * (edit) 2. +,- (preprocess) 3. (compile) 4. ./ (link) 5. 01 (load)

� 2-6

using std::endl;

// -- 程式主體部份 ---------------------

int main()

{

cout << "Hello, 您好!" // 主要的敘述

<< endl;

return 0;

}

這個程式包括了註解、前處理指令以及程式主體三個部份:

1. 註解 (comments)

在下列程式中的粗體字部份是程式的註解部份:

// Test.cpp

// 程式的目的是在顯示器上顯示一行文字

#include <iostream>

using std::cout;

using std::endl;

// -- 程式主體部份 ---------------------

int main()

{

cout << "Hello, 您好!" // 主要的敘述

<< endl;

return 0;

}

程式註解是加於程式原始碼內的說明文字,在編譯的時候就會被移除,

與程式的執行無關。話雖如此,註解仍是程式撰寫的時候重要的組成份子,

其目的如下:

1. 在每個檔案的開頭置入一段文字,以說明其目的、使用方式以及修改日

期等記錄,以便於日後追查。

2. 補充說明變數和函數等自行定義的元件之意義,以及使用上的注意事項。

3. 插入程式段落的特殊分界符號,使程式更容易閱讀。

Page 7: CHAPTER C++ - 碁峰資訊epaper.gotop.com.tw/pdf/ACL018800.pdf · 2-2 2.1 CPU C++ !"#$%&'() 1. * (edit) 2. +,- (preprocess) 3. (compile) 4. ./ (link) 5. 01 (load)

第二章 C++ 的基本語法和使用環境

2-7 �

4. 在撰寫程式時,為了除錯上的方便,常可將程式的某些部份暫時轉成註

解。如此一來,就可以不用真的把該部份程式刪除,隨時可以恢復,避

免無謂的重複輸入。

註解有兩種做法:

1. 從雙斜線「//」的右邊開始,一直到整行結束,都視為註解。

2. 以「/*」開頭,一直到「*/」,中間所包括的文數字或符號都視為註解。

因此,上述程式的註解部份也可以寫成下列形式:

/* Test.cpp

程式的目的是在顯示器上顯示一行文字 */

#include <iostream>

using std::cout;

using std::endl;

/* -- 程式主體部份 ---------------*/

int main()

{

cout << "Hello, 您好!" /* 主要的敘述 */

<< endl;

return 0;

}

除了第 4 種註解的目的 (也就是除錯的過程,要一次將許多行都轉為註

解) 之外,我們通常使用雙斜線的註解法。

2. 前處理指令 (preprocessor directives)

在下列程式中的粗體字部份是對前處理器 (preprocessor) 下指令的地

方,稱為前處理指令:

// Test.cpp

// 程式的目的是在顯示器上顯示一行文字

#include <iostream>

using std::cout;

using std::endl;

Page 8: CHAPTER C++ - 碁峰資訊epaper.gotop.com.tw/pdf/ACL018800.pdf · 2-2 2.1 CPU C++ !"#$%&'() 1. * (edit) 2. +,- (preprocess) 3. (compile) 4. ./ (link) 5. 01 (load)

� 2-8

// -- 程式主體部份 ---------------------

int main()

{

cout << "Hello, 您好!" // 主要的敘述

<< endl;

return 0;

}

以符號 # 開頭的指令行在程式編譯前就會由前處理器先行處理,每個前

處理指令都必需佔據獨立的一行指令。本例

#include <iostream>

的意義是要求將掌管「輸入 /輸出資料流」的標頭檔 (header file) <iostream>

包括進程式裏面,以引入相關的程式庫。在本例是讓我們能使用「cout」、

「endl」,和運算子「<<」。程式裡面引用的相關元件、函數、常數、運算

子等必需和標頭檔所指定的程式庫一致才能使用。正確的標頭檔是 C++ 程式

開發的重要元素,我們已將標準程式庫的常用標頭檔整理放在附錄 C,方便

讀者隨時參考。指令行

using std::cout;

using std::endl;

稱為 using 宣告 (using declaration),說明「cout」和「endl」是名稱空間 std

中的標準元件,即將在程式中使用。std 是 standard (標準) 的縮寫,而名稱空

間 (namespace) 是 C++ 的一種新的機制,其目的是為了避免分成很多檔案的

大型程式間發生變數名稱重覆的問題。我們會在第十一章介紹前處理指令,

隨後在第十六章介紹名稱空間。

3. 程式主體

在下列程式中的粗體字部份是程式的主體部份:

// Test.cpp

// 程式的目的是在顯示器上顯示一行文字

#include <iostream>

Page 9: CHAPTER C++ - 碁峰資訊epaper.gotop.com.tw/pdf/ACL018800.pdf · 2-2 2.1 CPU C++ !"#$%&'() 1. * (edit) 2. +,- (preprocess) 3. (compile) 4. ./ (link) 5. 01 (load)

第二章 C++ 的基本語法和使用環境

2-9 �

using std::cout;

using std::endl;

// -- 程式主體部份 ---------------------

int main()

{

cout << "Hello, 您好!" // 主要的敘述

<< endl;

return 0;

}

在 main之後的小括號 () 表示 main是一個程式的組成單元,稱為函數

(function)。C++ 程式可能含有一個或一個以的函數,但只能有一個叫做

main。為了在敘述中強調 main 是一個函數,我們在以下的說明中將寫成

main()。

不管 main() 是不是程式中第一個出現的函數,程式都是從 main() 開

始執行。在 main() 左邊的關鍵字 int表示 main() 的執行結果將會傳回一

個整數, int 是 integer (整數) 的縮寫。

關鍵字 (key word) 是 C++ 語法內的保留字,具有特定的意義,不可以更動。

在 main() 後面的大括號 { } 所涵蓋的部份是每個函數的本體部份

(function body)。我們將在第六章介紹函數的完整語法。

在大括號內的指令

cout << "Hello, 您好!" << endl;

才是這個 C++ 程式最主要的目的。完整的指令稱為敘述 (statement),每一個

敘述都是以分號「;」做為結尾。在這個輸出敘述中 "Hello, 您好 !" 稱為字

串,我們使用運算子「<<」將這個字串送到輸的標準輸出單元,也就是顯示

器上。