2020年8月11日星期二

001 C++ Primer Plus(第6版)中文版 第1章 預備知識

申明本站飛宇網 https://feiyetopro.blogspot.com/自網路收集整理之書籍文章影音僅供預覽交流學習研究,其[書籍、文章、影音]情節內容, 評論屬其個人行為, 與本網站無關。版權歸原作者和出版社所有,請在下載 24 小時內刪除,不得用作商業用途;如果您喜歡其作品,請支持訂閱購買[正版]謝謝!


C++ Primer Plus(第6版)中文版  


第1章 預備知識


本章內容包括:
  • C語言和C++的發展歷史和基本原理。
  • 過程性程式設計和物件導向程式設計。
  • C++是如何在C語言的基礎上添加物件導向概念的。
  • C++是如何在C語言的基礎上添加泛型程式設計概念的。
  • 程式設計語言標準。
  • 創建程式的技巧。
歡迎進入C++世界!這是一種令人興奮的語言,它在C語言的基礎上添加了對物件導向程式設計和泛型程式設計的支持,在20世紀90年代便是最重要的程式設計語言之一,並在21世紀仍保持強勁勢頭。C++繼承了C語言高效、簡潔、快速和可攜性的傳統。C++物件導向的特性帶來了全新的程式設計方法,這種方法是為應付複雜程度不斷提高的現代程式設計任務而設計的。C++的範本特性提供了另一種全新的程式設計方法——泛型程式設計。這三件法寶既是福也是禍,一方面讓C++語言功能強大,另一方面則意味著有更多的東西需要學習。
本章首先介紹C++的背景,然後介紹創建C++程式的一些基本原則。本書其他章節將講述如何使用C++語言,從最淺顯的基本知識開始,到物件導向的程式設計(OOP)及其支援的新術語——物件、類、封裝、資料隱藏、多態和繼承等,然後介紹它對泛型程式設計的支持(當然,隨著您對C++的學習,這些詞彙將從花裡胡哨的詞語變為論述中必不可少的術語)。
C++融合了3種不同的程式設計方式:C語言代表的過程性語言、C++在C語言基礎上添加的類代表的物件導向語言、C++範本支援的泛型程式設計。本章將簡要介紹這些傳統。不過首先,我們來看看這種傳統對於學習C++來說意味著什麼。使用C++的原因之一是為了利用其物件導向的特性。要利用這種特性,必須對標準C語言知識有較深入的瞭解,因為它提供了基本類型、運算子、控制結構和語法規則。所以,如果已經對C有所瞭解,便可以學習C++了,但這並不僅僅是學習更多的關鍵字和結構,從C過渡到C++的學習量就像從頭學習C語言一樣大。另外,如果先掌握了C語言,則在過渡到C++時,必須擯棄一些程式設計習慣。如果不瞭解C語言,則學習C++時需要掌握C語言的知識、OOP知識以及泛型程式設計知識,但無需擯棄任何程式設計習慣。如果您認為學習C++可能需要擴展思維,這就對了。本書將以清晰的、説明的方式,引導讀者一步一個腳印地學習,因此擴展思維的過程是溫和的,不至於讓您的大腦接受不了。
本書通過傳授C語言基礎知識和C++新增的內容,帶您步入C++的世界,因此不要求讀者具備C語言知識。首先學習C++與C語言共有的一些特性。即使已經瞭解C語言,也會發現閱讀本書的這一部分是一次很好的複習。另外,本章還介紹了一些對後面的學習十分重要的概念,指出了C++和C之間的區別。在牢固地掌握了C語言的基礎知識後,就可以在此基礎上學習C++方面的知識了。那時將學習物件和類以及C++是如何實現它們的,另外還將學習範本。
本書不是完整的C++參考手冊,不會探索該語言的每個細節,但將介紹所有的重要特性,包括範本、異常和名稱空間等。
下面簡要地介紹一下C++的背景知識。
在過去的幾十年,電腦技術以令人驚訝的速度發展著,當前,筆記型電腦的計算速度和存儲資訊的能力超過了20世紀60年代的大型機。很多程式師可能還記得,將數疊穿孔卡片提交給充斥整個房間的大型電腦系統的時代,而這種系統只有100KB的記憶體,比當今智慧手機的記憶體都少得多。電腦語言也得到了發展,儘管變化可能不是天翻地覆的,但也是非常重要的。體積更大、功能更強的電腦引出了更大、更複雜的程式,而這些程式在程式管理和維護方面帶來了新的問題。
在20世紀70年代,C和Pascal這樣的語言引領人們進入了結構化程式設計時代,這種機制把秩序和規程帶進了迫切需要這種性質的領域中。除了提供結構化程式設計工具外,C還能生成簡潔、快速運行的程式,並提供了處理硬體問題的能力,如管理通訊連接埠和磁碟機。這些因素使C語言成為20世紀80年代占統治地位的程式設計語言。同時,20世紀80年代,人們也見證了一種新程式設計模式的成長:物件導向程式設計(OOP)。SmallTalk和C++語言具備這種功能。下面更深入地介紹C和OOP。
20世紀70年代早期,貝爾實驗室的Dennis Ritchie致力於開發UNIX作業系統(作業系統是能夠管理電腦資源、處理電腦與使用者之間交互的一組程式。例如,作業系統將系統提示符顯示在螢幕上以提供終端式介面、提供管理視窗和滑鼠的圖形介面以及運行程式)。為完成這項工作,Ritchie需要一種語言,它必須簡潔,能夠生成簡潔、快速的程式,並能有效地控制硬體。
傳統上,程式師使用組合語言來滿足這些需求,組合語言依賴於電腦的內部機器語言。然而,組合語言是低級(low-level)語言,即直接操作硬體,如直接訪問CPU寄存器和記憶體單元。因此組合語言針對於特定的電腦處理器,要將組合語言程式移植到另一種電腦上,必須使用不同的組合語言重新編寫程式。這有點像每次購買新車時,都發現設計人員改變了控制系統的位置和功能,客戶不得不重新學習駕駛。
然而,UNIX是為在不同的電腦(或平臺)上工作而設計的,這意味著它是一種高階語言。高級(high-level)語言致力於解決問題,而不針對特定的硬體。一種被稱為編譯器的特殊程式將高階語言翻譯成特定電腦的內部語言。這樣,就可以通過對每個平臺使用不同的編譯器來在不同的平臺上使用同一個高階語言程式了。Ritchie希望有一種語言能將低階語言的效率、硬體訪問能力和高階語言的通用性、可攜性融合在一起,於是他在舊語言的基礎上開發了C語言。
由於C++在C語言的基礎上移植了新的程式設計理念,因此我們首先來看一看C所遵循的舊的理念。一般來說,電腦語言要處理兩個概念——資料和演算法。資料是程式使用和處理的資訊,而演算法是程式使用的方法(參見圖1.1)。C語言與當前最主流的語言一樣,在最初面世時也是過程性(procedural)語言,這意味著它強調的是程式設計的演算法方面。從概念上說,過程化程式設計首先要確定電腦應採取的操作,然後使用程式設計語言來實現這些操作。程式命令電腦按一系列流程生成特定的結果,就像菜譜指定了廚師做蛋糕時應遵循的一系列步驟一樣。
隨著程式規模的擴大,早期的程式語言(如FORTRAN和BASIC)都會遇到組織方面的問題。例如,程式經常使用分支語句,根據某種測試的結果,執行一組或另一組指令。很多舊式程式的執行路徑很混亂(被稱為“義大利麵條式程式設計”),幾乎不可能通過閱讀程式來理解它,修改這種程式簡直是一場災難。為了解決這種問題,電腦科學家開發了一種更有序的程式設計方法——結構化程式設計(structured programming)。C語言具有使用這種方法的特性。例如,結構化程式設計將分支(決定接下來應執行哪個指令)限制為一小組行為良好的結構。C語言的詞彙表中就包含了這些結構(for迴圈、while迴圈、do while迴圈和if else語句)。
另一個新原則是自頂向下(top-down)的設計。在C語言中,其理念是將大型程式分解成小型、便於管理的任務。如果其中的一項任務仍然過大,則將它分解為更小的任務。這一過程將一直持續下去,直到將程式劃分為小型的、易於編寫的模組(整理一下書房。先整理桌子、桌面、檔案櫃,然後整理書架。好,先從桌子開始,然後整理每個抽屜,從中間的那個抽屜開始整理。也許我都可以管理這項任務)。C語言的設計有助於使用這種方法,它鼓勵程式師開發程式單元(函數)來表示各個任務模組。如上所述,結構化程式設計技術反映了過程性程式設計的思想,根據執行的操作來構思一個程式。

圖1.1 資料+演算法=程式
雖然結構化程式設計的理念提高了程式的清晰度、可靠性,並使之便於維護,但它在編寫大型程式時,仍面臨著挑戰。為應付這種挑戰,OOP提供了一種新方法。與強調演算法的過程性程式設計不同的是,OOP強調的是資料。OOP不像過程性程式設計那樣,試圖使問題滿足語言的過程性方法,而是試圖讓語言來滿足問題的要求。其理念是設計與問題的本質特性相對應的資料格式。
在C++中,類是一種規範,它描述了這種新型資料格式,物件是根據這種規範構造的特定資料結構。例如,類可以描述公司管理人員的基本特徵(姓名、頭銜、工資、特長等),而物件則代表特定的管理人員(Guilford Sheepblat、副總裁、$925 000、知道如何恢復Windows註冊表)。通常,類規定了可使用哪些資料來表示物件以及可以對這些資料執行哪些操作。例如,假設正在開發一個能夠繪製矩形的電腦繪圖程式,則可以定義一個描述矩形的類。定義的資料部分應包括頂點的位置、長和寬、4條邊的顏色和樣式、矩形內部的填充顏色和圖案等;定義的操作部分可以包括移動、改變大小、旋轉、改變顏色和圖案、將矩形複製到另一個位置上等操作。這樣,當使用該程式來繪製矩形時,它將根據類定義創建一個物件。該物件保存了描述矩形的所有資料值,因此可以使用類方法來修改該矩形。如果繪製兩個矩形,程式將創建兩個物件,每個矩形對應一個。
OOP程式設計方法首先設計類,它們準確地表示了程式要處理的東西。例如,繪圖程式可能定義表示矩形、直線、圓、畫刷、畫筆的類。類定義描述了對每個類可執行的操作,如移動圓或旋轉直線。然後您便可以設計一個使用這些類的物件的程式。從低級組織(如類)到高級組織(如程式)的處理過程叫做自下向上(bottom-up)的程式設計。
OOP程式設計並不僅僅是將資料和方法合併為類定義。例如,OOP還有助於創建可重用的代碼,這將減少大量的工作。資訊隱藏可以保護資料,使其免遭不適當的訪問。多態讓您能夠為運算子和函數創建多個定義,通過程式設計上下文來確定使用哪個定義。繼承讓您能夠使用舊類派生出新類。正如接下來將看到的那樣,OOP引入了很多新的理念,使用的程式設計方法不同於過程性程式設計。它不是將重點放在任務上,而是放在表示概念上。有時不一定使用自上向下的程式設計方法,而是使用自下向上的程式設計方法。本書將通過大量易於掌握的示例幫助讀者理解這些要點。
設計有用、可靠的類是一項艱巨的任務,幸運的是,OOP語言使程式師在程式設計中能夠輕鬆地使用已有的類。廠商提供了大量有用的類庫,包括設計用於簡化Windows或Macintosh環境下程式設計的類庫。C++真正的優點之一是:可以方便地重用和修改現有的、經過仔細測試的代碼。
泛型程式設計(generic programming)是C++支援的另一種程式設計模式。它與OOP的目標相同,即使重用代碼和抽象通用概念的技術更簡單。不過OOP強調的是程式設計的資料方面,而泛型程式設計強調的是獨立於特定資料類型。它們的側重點不同。OOP是一個管理大型專案的工具,而泛型程式設計提供了執行常見任務(如對資料排序或合併鏈表)的工具。術語泛型(generic)指的是創建獨立於類型的代碼。C++的資料表示有多種類型——整數、小數、字元、字串、使用者定義的、由多種類型組成的複合結構。例如,要對不同類型的資料進行排序,通常必須為每種類型創建一個排序函數。泛型程式設計需要對語言進行擴展,以便可以只編寫一個泛型(即不是特定類型的)函數,並將其用於各種實際類型。C++範本提供了完成這種任務的機制。
與C語言一樣,C++也是在貝爾實驗室誕生的,Bjarne Stroustrup於20世紀80年代在這裡開發出了這種語言。用他自己的話來說,“C++主要是為了我的朋友和我不必再使用組合語言、C語言或其他現代高階語言來程式設計而設計的。它的主要功能是可以更方便地編寫出好程式,讓每個程式師更加快樂”。
Bjarne Stroustrup的主頁

Bjarne Stroustrup設計並實現了C++程式設計語言,他是權威參考手冊《The C++ Programming Language》和《The design and Evolution of C++》的作者。讀者應將他位於AT&T Labs Research上的個人網站作為首選的C++書簽:
http://www.research.att.com/-bs/
該網站包括了C++語言有趣的發展歷史、Bjarne的傳記材料和C++ FAQ。Bjarne被問得最多的問題是:Bjarne Stroustrup應該如何讀。您可以訪問Stroustrup的網站,閱讀FAQ部分並下載.WAV文件,親自聽一聽。
Stroustrup比較關心的是讓C++更有用,而不是實施特定的程式設計原理或風格。在確定C++語言特性方面,真正的程式設計需要比純粹的原理更重要。Stroupstrup之所以在C的基礎上創建C++,是因為C語言簡潔、適合系統程式設計、使用廣泛且與UNIX作業系統聯繫緊密。C++的OOP方面是受到了電腦類比語言Simula67的啟發。Stroustrup加入了OOP特性和對C的泛型程式設計支持,但並沒有對C的組件作很大的改動。因此,C++是C語言的超集合,這意味著任何有效的C程式都是有效的C++程式。它們之間有些細微的差異,但無足輕重。C++程式可以使用已有的C軟體庫。庫是程式設計模組的集合,可以從程式中調用它們。庫對很多常見的程式設計問題提供了可靠的解決方法,因此能節省程式師大量的時間和工作量。這也有助於C++的廣泛傳播。
名稱C++來自C語言中的遞增運算子++,該運算子將變數加1。名稱C++表明,它是C的擴充版本。
電腦程式將實際問題轉換為電腦能夠執行的一系列操作。OOP部分賦予了C++語言將問題所涉及的概念聯繫起來的能力,C部分則賦予了C++語言緊密聯繫硬體的能力(參見圖1.2),這種能力上的結合成就了C++的廣泛傳播。從程式的一個方面轉到另一個方面時,思維方式也要跟著轉換(確實,有些OOP正統派把為C添加OOP特性看作是為豬插上翅膀,雖然這是頭瘦骨嶙峋、非常能幹的豬)。另外,C++是在C語言的基礎上添加OOP特性,您可以忽略C++的物件導向特性,但將錯過很多有用的東西。
在C++獲得一定程度的成功後,Stroustrup才添加了範本,這使得進行泛型程式設計成為可能。在範本特性被使用和改進後,人們才逐漸認識到,它們和OOP同樣重要——甚至比OOP還重要,但有些人不這麼認為。C++融合了OOP、泛型程式設計和傳統的過程性方法,這表明C++強調的是實用價值,而不是意識形態方法,這也是該語言獲得成功的原因之一。

圖1.2 C++的二重性
假設您為運行Windows 2000的老式奔騰PC編寫了一個很好用的C++程式,而管理人員決定用使用不同作業系統(如Mac OS X或Linux)和處理器(如SPARC處理器)的電腦替換它。該程式是否可以在新平臺上運行呢?當然,必須使用為新平臺設計的C++編譯器對程式重新編譯。但是否需要修改編寫好的代碼呢?如果在不修改代碼的情況下,重新編譯器後,程式將運行良好,則該程式是可移植的。
在可攜性方面存在兩個障礙,其中的一個是硬體。硬體特定的程式是不可移植的。例如,直接控制IBM PC 視訊卡的程式在涉及Sun時將“胡言亂語”(將依賴於硬體的部分放在函數模組中可以最大限度地降低可攜性問題;這樣只需重新編寫這些模組即可)。本書將避免這種程式設計。
可攜性的第二個障礙是語言上的差異。口語確實可能產生問題。約克郡的人對某個事件的描述,布魯克林人可能就聽不明白,雖然這兩個地方的人都說英語。電腦語言也可能出現方言。Windows XP C++的實現與Red Hat Linux或Macintosh OS X實現相同嗎?雖然多數實現都希望其C++版本與其他版本相容,但如果沒有準確描述語言工作方式的公開標準,這將很難做到。因此,美國國家標準局(American National Standards Institute,ANSI)在1990年設立了一個委員會(ANSI X3J16),專門負責制定C++標準(ANSI制定了C語言標準)。國際標準組織(ISO)很快通過自己的委員會(ISO-WG-21)加入了這個行列,創建了聯合組織ANSI/ISO,致力於制定C++標準。
經過多年的努力,制定出了一個國際標準ISO/IEC 14882:1998,並於1998年獲得了ISO、IEC(International Electrotechnical Committee,國際電工技術委員會)和ANSI的批准。該標準常被稱為C++98,它不僅描述了已有的C++特性,還對該語言進行了擴展,添加了異常、運行階段類型識別(RTTI)、範本和標準範本庫(STL)。2003年,發佈了C++標準第二版(IOS/IEC 14882:2003);這個新版本是一次技術性修訂,這意味著它對第一版進行了整理——修訂錯誤、減少多義性等,但沒有改變語言特性。這個版本常被稱為C++03。由於C++03沒有改變語言特性,因此我們使用C++98表示C++98/C++2003。
C++在不斷發展。ISO標準委員會於2001年8月批准了新標準ISO/IEC 14882:2011,該標準以前稱為C++11。與C++98一樣,C++11也新增了眾多特性。另外,其目標是消除不一致性,讓C++學習和使用起來更容易。該標準還曾被稱為C++0x,最初預期x為7或8,但標準制定工作是一個令人疲憊的緩慢過程。所幸的是,可將0x視為十六進位數,這意味著委員會只需在2015年前完成這項任務即可。根據這個度量標準,委員會還是提前完成了任務。
ISO C++標準還吸收了ANSI C語言標準,因為C++應儘量是C語言的超集合。這意味著在理想情況下,任何有效的C程式都應是有效的C++程式。ANSI C與對應的C++規則之間存在一些差別,但這種差別很小。實際上,ANSI C加入了C++首次引入的一些特性,如函數原型和類型限定詞const。
在ANSI C出現之前,C語言社區遵循一種事實標準,該標準基於Kernighan和Ritchie編寫的《The C Programming Language》一書,通常被稱為K&R C;ANSI C出現後,更簡單的K&R C有時被稱為經典C(Classic C)。
ANSI C標準不僅定義了C語言,還定義了一個ANSI C實現必須支持的標準C庫。C++也使用了這個庫;本書將其稱為標準C庫或標準庫。另外,ANSI/ISO C++標準還提供了一個C++標準類庫。
最新的C標準為C99,ISO和ANSI分別於1999年和2000年批准了該標準。該標準在C語言中添加了一些C++編譯器支持的特性,如新的整型。
Stroustrup編寫的《The Programming Language》包含65頁的參考手冊,它成了最初的C++事實標準。
下一個事實標準是Ellis和Stroustrup編寫的《The Annotated C++ Reference Manual》。
C++98標準新增了大量特性,其篇幅將近800頁,且包含的說明很少。
C++11標準的篇幅長達1350頁,對舊標準做了大量的補充。
當代的編譯器都對C++98提供了很好的支援。編寫本書期間,有些編譯器還支持一些C++特性;隨著新標準獲批,對這些特性的支持將很快得到提高。本書反映了當前的情形,詳盡地介紹了C++98,並涵蓋了C++11新增的一些特性。在探討相關的C++98主題時順便介紹了一些C++新特性,而第18章專門介紹新特性,它總結了本書前面提到的一些特性,並介紹了其他特性。
在編寫本書期間,對C++11的支持還不全面,因此難以全面介紹C++11新增的所有特性。考慮到篇幅限制,即使這個新標準獲得了全面支持,也無法在一本書中全面介紹它。本書重點介紹大多數編譯器都支持的特性,並簡要地總結其他特性。
詳細介紹C++之前,先介紹一些有關程式創建的基本知識。
假設您編寫了一個C++程式。如何讓它運行起來呢?具體的步驟取決於電腦環境和使用的C++編譯器,但大體如下(參見圖1.3)。
1.使用文字編輯器編寫程式,並將其保存到檔中,這個檔就是程式的原始程式碼。
2.編譯原始程式碼。這意味著運行一個程式,將原始程式碼翻譯為主機使用的內部語言——機器語言。包含了翻譯後的程式的檔就是程式的目標代碼(object code)。
3.將目標代碼與其他代碼連結起來。例如,C++程式通常使用庫。C++庫包含一系列電腦常式(被稱為函數)的目標代碼,這些函數可以執行諸如在螢幕上顯示資訊或計算平方根等任務。連結指的是將目標代碼同使用的函數的目標代碼以及一些標準的啟動代碼(startup code)組合起來,生成程式的運行階段版本。包含該最終產品的檔被稱為可執行代碼。

圖1.3 程式設計步驟
本書將不斷使用術語原始程式碼,請記住該術語。
本書的程式都是通用的,可在任何支援C++98的系統中運行;但第18章的程式要求系統支援C++11。編寫本書期間,有些編譯器要求您使用特定的標記,讓其支援部分C++11特性。例如,從4.3版起,g++要求您編譯原始程式碼檔時使用標記-std=c++0x:
創建程式的步驟可能各不相同,下面深入介紹這些步驟。
本書餘下的篇幅討論原始程式碼檔中的內容;本節討論創建原始程式碼文件的技巧。有些C++實現(如Microsoft Visual C++、Embarcadero C++ Builder、Apple Xcode、Open Watcom C++、Digital Mars C++和Freescale CodeWarrior)提供了整合式開發環境(integrated development environments,IDE),讓您能夠在主程序中管理程式開發的所有步驟,包括編輯。有些實現(如用於UNIX和Linux的GNU C++、用於AIX的IBM XL C/C++、Embarcadero分發的Borland 5.5免費版本以及Digital Mars編譯器)只能處理編譯和連結階段,要求在系統命令列輸入命令。在這種情況下,可以使用任何文字編輯器來創建和修改原始程式碼。例如,在UNIX系統上,可以使用vi、ed、ex或emacs;在以命令提示符模式運行的Windows系統上,可以使用edlin、edit或任何程式編輯器。如果將檔保存為標準ASCII文字檔(而不是特殊的文書處理器格式),甚至可以使用文書處理器。另外,還可能有IDE選項,讓您能夠使用這些命令列編譯器。
給原始檔案命名時,必須使用正確的尾碼,將檔標識為C++檔。這不僅告訴您該檔是C++原始程式碼,還將這種資訊告知編譯器(如果UNIX編譯器顯示資訊“bad magic number”,則表明尾碼不正確)。尾碼由一個句點和一個或多個字元組成,這些字元被稱作副檔名(參見圖1.4)。

圖1.4 原始檔案的副檔名
使用什麼副檔名取決於C++實現,表1.1列出了一些常用的副檔名。例如,spiffy.C是有效的UNIX C++原始程式碼檔案名。注意,UNIX區分大小寫,這意味著應使用大寫的C字元。實際上,小寫c副檔名也有效,但標準C才使用小寫的c。因此,為避免在UNIX系統上發生混淆,對於C程式應使用c,而對於C++程式則請使用C。如果不在乎多輸入一兩個字元,則對於某些UNIX系統,也可以使用副檔名cc和cxx。DOS比UNIX稍微簡單一點,不區分大小寫,因此DOS實現使用額外的字母(如表1.1所示)來區別C和C++程式。
表1.1 原始程式碼文件的副檔名
C++實現
原始程式碼文件的副檔名
UNIX
C、cc、cxx、c
GNU C++
C、cc、cxx、cpp、c++
Digital Mars
cpp、cxx
Borland C++
cpp
Watcom
cpp
Microsoft Visual C++
cpp、cxx、cc
Freestyle CodeWarrior
cp、cpp、cc、cxx、c++
最初,Stroustrup實現C++時,使用了一個C++到C的編譯器程式,而不是開發直接的C++到目標代碼的編譯器。前者叫做cfront(表示C前端,C front end),它將C++原始程式碼翻譯成C原始程式碼,然後使用一個標準C編譯器對其進行編譯。這種方法簡化了向C的領域引入C++的過程。其他實現也採用這種方法將C++引入到其他平臺。隨著C++的日漸普及,越來越多的實現轉向創建C++編譯器,直接將C++原始程式碼生成目標代碼。這種直接方法加速了編譯過程,並強調C++是一種獨立(雖然有些相似)的語言。
編譯的機理取決於實現,接下來的幾節將介紹一些常見的形式。這些總結概括了基本步驟,但對於具體步驟,必須查看系統文檔。

1.UNIX編譯和連結

最初,UNIX命令CC調用cfront,但cfront未能緊跟C++的發展步伐,其最後一個版本發佈於1993年。當今的UNIX電腦可能沒有編譯器、有專用編譯器或協力廠商編譯器,這些編譯器可能是商業的,也可能是自由軟體,如GNU g++編譯器。如果UNIX電腦上有C++編譯器,很多情況下命令CC仍然管用,只是啟動的編譯器隨系統而異。出於簡化的目的,讀者應假設命令CC可用,但必須認識到這一點,即對於下述討論中的CC,可能必須使用其他命令來代替。
請用CC命令來編譯器。名稱採用大寫字母,這樣可以將它與標準UNIX C編譯器cc區分開來。CC編譯器是命令列編譯器,這意味著需要在UNIX命令列上輸入編譯命令。
例如,要編譯C++原始程式碼檔spiffy.C,則應在UNIX提示符下輸入如下命令:
CC spiffy.C
如果由於技巧、努力或是幸運的因素,程式沒有錯誤,編譯器將生成一個副檔名為o的目標代碼檔。在這個例子中,編譯器將生成檔spiffy.o。
接下來,編譯器自動將目標代碼檔傳遞給系統連結程式,該程式將代碼與庫代碼結合起來,生成一個可執行檔。在預設情況下,可執行檔為a.out。如果只使用一個原始檔案,連結程式還將刪除spiffy.o檔,因為這個檔不再需要了。要運行該程式,只要輸入可執行檔的檔案名即可:
a.out
注意,如果編譯新程式,新的可執行檔a.out將覆蓋已有的a.out(這是因為可執行檔佔據了大量空間,因此覆蓋舊的可執行檔有助於降低存儲需求)。然而,如果想保留可執行檔,只需使用UNIX的mv命令來修改可執行檔的檔案名即可。
與在C語言中一樣,在C++中,程式也可以包含多個檔(本書第8~第16章的很多程式都是這樣)。在這種情況下,可以通過在命令列上列出全部檔來編譯器:
CC my.C precious.C
如果有多個原始程式碼檔,則編譯器將不會刪除目標代碼檔。這樣,如果只修改了my.C檔,則可以用下面的命令重新編譯該程式:
CC my.C precious.o
這將重新編譯my.C檔,並將它與前面編譯的precious.o檔連結起來。
可能需要顯式地指定一些庫。例如,要訪問數學庫中定義的函數,必須在命令列中加上-lm標記:
CC usingmath.C -lm

2.Linux編譯和連結

Linux系統中最常用的編譯器是g++,這是來自Free Software Foundation的GNU C++編譯器。Linux的多數版本都包括該編譯器,但並不一定總會安裝它。g++編譯器的工作方式很像標準UNIX編譯器。例如,下麵的命令將生成可執行檔a.out
g++ spiffy.cxx
有些版本可能要求連結C++庫:
g++ spiffy.cxx -lg++
要編譯多個原始檔案,只需將它們全部放到命令列中即可:
g++ my.cxx precious.cxx
這將生成一個名為a.out的可執行檔和兩個目標代碼檔my.o和precious.o。如果接下來修改了其中的某個原始程式碼檔,如mu.cxx,則可以使用my.cxx和precious.o來重新編譯:
g++ my.cxx precious.o
GNU編譯器可以在很多平臺上使用,包括基於Windows的PC和在各種平臺上運行的UNIX系統。

3.Windows命令列編譯器

要在Windows PC上編譯C++程式,最便宜的方法是下載一個在Windows命令提示符模式(在這種模式下,將打開一個類似於MS-DOS的視窗)下運行的免費命令列編譯器。Cygwin和MinGW都包含編譯器GNU C++,且可免費下載;它們使用的編譯器名為g++。
要使用g++編譯器,首先需要打開一個命令提示視窗。啟動程式Cygwin和MinGW時,它們將自動為您打開一個命令提示視窗。要編譯名為great.cpp的原始程式碼文件,請在提示符下輸入如下命令:
g++ great.cpp
如果程式編譯成功,則得到的可執行檔名為a.exe。

4.Windows編譯器

Windows產品很多且修訂頻繁,無法對它們分別進行介紹。當前,最流行是Microsoft Visual C++ 2010,可通過免費的Microsoft Visual C++ 2010學習版獲得。雖然設計和目標不同,但大多數基於Windows的C++編譯器都有一些相同的功能。
通常,必須為程式創建一個專案,並將組成程式的一個或多個檔添加到該專案中。每個廠商提供的IDE(整合式開發環境)都包含用於創建項目的功能表選項(可能還有自動幫助)。必須確定的非常重要的一點是,需要創建的是什麼類型的程式。通常,編譯器提供了很多選擇,如Windows應用程式、MFC Windows應用程式、動態連結程式庫、ActiveX控制項、DOS或字元模式的可執行檔、靜態程式庫或控制台應用程式等。其中一些可能既有32位版本,又有64位版本。
由於本書的程式都是通用的,因此應當避免要求平臺特定代碼的選項,如Windows應用程式。相反,應讓程式以字元模式運行。具體選項取決於編譯器。一般而言,應選擇包含字樣“控制台”、“字元模式”或“DOS可執行檔”等選項。例如,在Microsoft Visual C++ 2010中,應選擇Win32 Console Application(控制台應用程式)選項,按一下Application Settings(應用程式設置),並選擇Empty Project(空項目)。在C++ Builder中,應從C++ Builder Projects(C++ Builder項目)中選擇Console Application(控制台應用程式)。
創建好專案後,需要對程式進行編譯和連結。IDE通常提供了多個功能表項目,如Compile(編譯)、Build(建立)、Make(生成)、Build All(全部建立)、Link(連結)、Execute(執行)、Run(運行)和Debug(調試),不過同一個IDE中,不一定包含所有這些選項。
  • Compile通常意味著對當前打開的檔中的代碼進行編譯。
  • Build和Make通常意味著編譯專案中所有原始程式碼檔的代碼。這通常是一個遞增過程,也就是說,如果專案包含3個檔,而只有其中一個檔被修改,則只重新編譯該檔。
  • Build All通常意味著重新編譯所有的原始程式碼檔。
  • Link意味著(如前所述)將編譯後的原始程式碼與所需的庫代碼組合起來。
  • Run或Execute意味著運行程式。通常,如果您還沒有執行前面的步驟,Run將在運行程式之前完成這些步驟。
  • Debug意味著以步進方式執行程式。
  • 編譯器可能讓您選擇要生成調試版還是發佈版。調試版包含額外的代碼,這會增大程式、降低執行速度,但可提供詳細的調試資訊。
如果程式違反了語言規則,編譯器將生成錯誤消息,指出存在問題的行。遺憾的是,如果不熟悉語言,將難以理解這些消息的含義。有時,真正的問題可能在標識行之前;有時,一個錯誤可能引發一連串的錯誤消息。
提示:

改正錯誤時,應首先改正第一個錯誤。如果在標識為有錯誤的那一行上找不到錯誤,請查看前一行。
需要注意的是,程式能夠通過某個編譯器的編譯並不意味著它是合法的C++程式;同樣,程式不能通過某個編譯器的編譯也並不意味著它是非法的C++程式。與幾年前相比,現在的編譯器更嚴格地遵循了C++標準。另外,編譯器通常提供了可用於控制嚴格程度的選項。
提示:

有時,編譯器在不完全地構建程式後將出現混亂,它顯示無法改正的、無意義的錯誤消息。在這種情況下,可以選擇Build All,重新編譯整個程式,以清除這些錯誤消息。遺憾的是,這種情況和那些更常見的情況(即錯誤消息只是看上去無意義,實際上有意義)很難區分。
通常,IDE允許在輔助視窗中運行程式。程式執行完畢後,有些IDE將關閉該視窗,而有些IDE不關閉。如果編譯器關閉視窗,將難以看到程式輸出,除非您眼疾手快、過目不忘。為查看輸出,必須在程式的最後加上一些代碼:
cin.get( )語句讀取下一次鍵擊,因此上述語句讓程式等待,直到按下了Enter鍵(在按下Enter鍵之前,鍵擊將不被發送給程式,因此按其他鍵都不管用)。如果程式在其常規輸入後留下一個沒有被處理的鍵擊,則第二條語句是必需的。例如,如果要輸入一個數位,則需要輸入該數位,然後按Enter鍵。程式將讀取該數位,但Enter鍵不被處理,這樣它將被第一個cin.get( )讀取。

5.Macintosh上的C++

當前,Apple隨作業系統Mac OS X提供了開發框架Xcode,該框架是免費的,但通常不會自動安裝。要安裝它,可使用作業系統安裝盤,也可從Apple網站免費下載(但需要注意的是,它超過4GB)。Xcode不僅提供了支援多種語言的IDE,還自帶了兩個命令列編譯器(g++和clang),可在UNIX模式下運行它們。而要進入UNIX模式,可通過實用程式Terminal。
提示:

為節省時間,可對所有示例程式使用同一個專案。方法是從專案清單中刪除前一個示例程式的原始程式碼檔,並添加當前的原始程式碼。這樣可節省時間、工作量和磁碟空間。
隨著電腦的功能越來越強大,電腦程式越來越龐大而複雜。為應對這種挑戰,電腦語言也得到了改進,以便程式設計過程更為簡單。C語言新增了諸如控制結構和函數等特性,以便更好地控制程式流程,支援結構化和模組化程度更高的方法;而C++增加了對物件導向程式設計和泛型程式設計的支持,這有助於提高模組化和創建可重用代碼,從而節省程式設計時間並提高程式的可靠性。
C++的流行導致大量用於各種計算平臺的C++實現得以面世;而ISOC++標準(C++98/03和C++11)為確保眾多實現的相互相容提供了基礎。這些標準規定了語言必須具備的特性、語言呈現出的行為、標準庫函數、類和範本,旨在實現該語言在不同計算平臺和實現之間的可攜性。
要創建C++程式,可創建一個或多個原始程式碼檔,其中包含了以C++語言表示的程式。這些檔是文字檔,它們經過編譯和連結後將得到機器語言檔,後者構成了可執行的程式。上述任務通常是在IDE中完成的,IDE提供了用於創建原始程式碼檔的文字編輯器、用於生成可執行檔的編譯器和連結器以及其他資源,如專案管理和調試功能。然而,這些任務也可以在命令列環境中通過調用合適的工具來完成。

0 留言:

發佈留言