第1章 C++介紹
1.1 程序與編程語(yǔ)言
1.1.1 計(jì)算機(jī)是什么
計(jì)算機(jī)是一種通用計(jì)算設(shè)備,能夠根據(jù)指令處理數(shù)據(jù)。每臺(tái)計(jì)算機(jī)都配備一個(gè) 中央處理單元(CPU),它是一塊微處理器芯片,負(fù)責(zé)執(zhí)行數(shù)據(jù)處理指令。不同的計(jì)算機(jī)可能使用不同的 指令集。
計(jì)算機(jī)指令
計(jì)算機(jī)通過執(zhí)行一系列指令來處理任務(wù),并通常會(huì)生成某種輸出。這類似于人們按照步驟完成任務(wù)的方式。例如,“做飯”可以分解為以下步驟:
- 取米并放入洗米盆。
- 用自來水沖洗大米。
- 如果電飯鍋未清洗,則清洗電飯鍋。
- 將米和水放入電飯鍋。
- 插上電源,按下開關(guān)。
- 飯煮好后,拔下電源(任務(wù)完成)。
雖然人類可以理解復(fù)雜的自然語(yǔ)言指令,但計(jì)算機(jī)只能處理簡(jiǎn)單的 機(jī)器指令,它們使用特定的計(jì)算機(jī)語(yǔ)言表示。無論多么復(fù)雜的計(jì)算任務(wù),計(jì)算機(jī)最終都會(huì)將其分解成一系列簡(jiǎn)單的、逐條執(zhí)行的 機(jī)器指令。這些指令的集合被稱為 程序。
以下是幾種常見的計(jì)算機(jī)指令:
- 算術(shù)運(yùn)算:執(zhí)行加、減、乘、除等運(yùn)算,通常稱為 算術(shù)操作。
- 邏輯運(yùn)算:比較兩個(gè)數(shù)值的大小或判斷它們是否相等,通常稱為 邏輯操作。
- 控制指令:改變程序執(zhí)行流程,如跳轉(zhuǎn)到特定指令,通常稱為 控制語(yǔ)句。
計(jì)算機(jī)的組成部分
計(jì)算機(jī)由四大類核心組件組成:
- 輸入設(shè)備:用于接收用戶輸入,例如鍵盤、鼠標(biāo)、掃描儀和麥克風(fēng)。
- 處理單元:執(zhí)行計(jì)算任務(wù)的組件,主要是 中央處理單元(CPU)?,F(xiàn)代計(jì)算機(jī)還可能配備 圖形處理單元(GPU),最初用于圖形處理,但如今也可用于通用計(jì)算。
- 存儲(chǔ)設(shè)備:包括 主存儲(chǔ)器(內(nèi)存) 和 二級(jí)存儲(chǔ)器(如硬盤、光盤、U 盤等),用于存儲(chǔ)程序和數(shù)據(jù)。
- 輸出設(shè)備:用于向用戶呈現(xiàn)計(jì)算結(jié)果,例如顯示器、揚(yáng)聲器和打印機(jī)。
示例:自動(dòng)售票機(jī)
雖然自動(dòng)售票機(jī)并不完全是計(jì)算機(jī),但它可以幫助理解計(jì)算機(jī)的基本組成部分:
- 輸入:投幣口和選擇按鈕用于接收用戶輸入。
- 處理:售票機(jī)執(zhí)行一系列計(jì)算,如驗(yàn)證票務(wù)信息、檢查余額、修改數(shù)據(jù)庫(kù)等。
- 存儲(chǔ):售票機(jī)需要存儲(chǔ)車票庫(kù)存、價(jià)格等信息。
- 輸出:顯示購(gòu)票結(jié)果并打印車票。
中央處理單元(CPU)
CPU 是計(jì)算機(jī)的核心,被稱為 計(jì)算機(jī)的大腦,負(fù)責(zé)計(jì)算、數(shù)據(jù)處理和設(shè)備控制。它主要由以下部分組成:
- 算術(shù)/邏輯單元(ALU):執(zhí)行數(shù)學(xué)運(yùn)算和邏輯判斷。
- 控制單元(CU):決定下一條要執(zhí)行的指令。
- 寄存器:高速存儲(chǔ)區(qū)域,用于存放臨時(shí)數(shù)據(jù)。
不同類型的 CPU 支持不同的 指令集,例如 Intel x86-64、IBM PowerPC 或 ARM。
存儲(chǔ)器
計(jì)算機(jī)將 程序 和 數(shù)據(jù) 存儲(chǔ)在 存儲(chǔ)器(Memory) 中,存儲(chǔ)器分為 主存儲(chǔ)器 和 輔助存儲(chǔ)器。
主存儲(chǔ)器(內(nèi)存,RAM)
- 直接連接 CPU,速度快。
- 斷電后數(shù)據(jù)會(huì)丟失(易失性)。
- 由多個(gè)存儲(chǔ)單元組成,每個(gè)單元都有唯一的地址,例如:存儲(chǔ)單元地址從
0開始,類似于學(xué)號(hào)編號(hào)。 - 每個(gè)存儲(chǔ)單元只能存儲(chǔ)固定大小的二進(jìn)制數(shù)據(jù),并可隨時(shí)被 CPU 讀取或修改。
輔助存儲(chǔ)器(外存)
- 存儲(chǔ)容量大,價(jià)格低,但訪問速度較慢。
- 斷電后數(shù)據(jù)不會(huì)丟失(非易失性)。
- 典型設(shè)備包括 硬盤、光盤、閃存盤等。
計(jì)算機(jī)的 操作系統(tǒng) 提供對(duì)輔助存儲(chǔ)器的管理,允許用戶以 文件 形式存儲(chǔ)數(shù)據(jù),并通過 文件系統(tǒng) 組織文件。例如,Windows 操作系統(tǒng)使用 資源管理器 訪問文件和目錄。
1.1.2 計(jì)算機(jī)編程
1. 算法(Algorithm)
算法 是完成特定任務(wù)或解決某個(gè)問題的一系列步驟(指令)。它類似于菜譜中的制作步驟或數(shù)學(xué)家祖沖之計(jì)算圓周率的方法。
2. 程序與編程
程序 是算法在計(jì)算機(jī)中的實(shí)現(xiàn),即計(jì)算機(jī)可執(zhí)行的指令序列。編程 則是將算法轉(zhuǎn)換為計(jì)算機(jī)可以理解的程序的過程,使用特定的計(jì)算機(jī)語(yǔ)言編寫指令,使計(jì)算機(jī)按照既定邏輯執(zhí)行任務(wù)。
3. 二進(jìn)制
計(jì)算機(jī)的底層硬件由大量 晶體管 組成,而晶體管只有 "開"(1)和 "關(guān)"(0)兩種狀態(tài)。因此,計(jì)算機(jī)采用 二進(jìn)制(0 和 1)來表示所有數(shù)據(jù),包括整數(shù)、字符等。
在計(jì)算機(jī)中,一個(gè)晶體管可以存儲(chǔ) 1 個(gè)二進(jìn)制位(bit,簡(jiǎn)稱 b),即 0 或 1。多個(gè)晶體管可以組合表示更復(fù)雜的數(shù)值。例如:
8 位(bit) 組成 1 字節(jié)(Byte,B),即
種不同的可能值。
1024 B = 1 KB(千字節(jié),Kilobyte)。
-
1024 KB = 1 MB(兆字節(jié),Megabyte)。
1024 MB = 1 GB(吉字節(jié),Gigabyte)*。
4. 機(jī)器語(yǔ)言
計(jì)算機(jī)內(nèi)部的指令和數(shù)據(jù)都是以 0 和 1 組成的 二進(jìn)制代碼 進(jìn)行存儲(chǔ)和處理。機(jī)器語(yǔ)言(Machine Language) 是計(jì)算機(jī)能夠直接理解和執(zhí)行的一種指令集合。
例如,以下是用 Intel 8086 機(jī)器語(yǔ)言執(zhí)行 17 + 20 的指令:
1011 0000 0001 0001 // 將 17 存入 AL 寄存器
0000 0100 0001 0100 // 將 20 加到 AL 寄存器
1010 0010 0100 1000 0000 0000 // 將 AL 的值存入內(nèi)存地址 0x0048
解析:
-
1011 0000是 操作碼(Opcode),表示“將后面的數(shù)存入寄存器 AL”。 -
0001 0001是 立即數(shù)(Immediate Value),即 17。 -
0000 0100指示 AL 執(zhí)行加法操作,0001 0100是 20 的二進(jìn)制表示。 -
1010 ...負(fù)責(zé)將結(jié)果存入指定內(nèi)存地址0x0048(采用 小端存儲(chǔ))。
早期編程的挑戰(zhàn)
在 20 世紀(jì) 40 年代,程序員必須直接使用機(jī)器語(yǔ)言進(jìn)行編程,甚至通過穿孔卡片輸入指令。這種方式既繁瑣又容易出錯(cuò),極大地限制了計(jì)算機(jī)的使用效率。
5. 匯編語(yǔ)言(Assembly Language)**
為了簡(jiǎn)化機(jī)器語(yǔ)言的編寫,引入了 匯編語(yǔ)言(Assembly Language)。匯編語(yǔ)言使用 助記符(Mnemonic) 代替二進(jìn)制代碼,使程序更易讀,例如:
MOV AL, 17D ; 將 17 存入 AL 寄存器
ADD AL, 20D ; 將 20 加到 AL 寄存器
MOV [0048H], AL ; 將 AL 的值存入內(nèi)存地址 0x0048
匯編語(yǔ)言的特點(diǎn)
- 每條匯編指令 對(duì)應(yīng)一條機(jī)器指令。
- 人類可讀,但仍然需要較高的技術(shù)背景。
- 需要 匯編程序(Assembler) 將匯編代碼轉(zhuǎn)換為機(jī)器語(yǔ)言,計(jì)算機(jī)才能執(zhí)行。
盡管匯編語(yǔ)言相較于機(jī)器語(yǔ)言更加直觀,但仍然對(duì)程序員要求較高,且代碼冗長(zhǎng),不利于開發(fā)大型程序。
6. 高級(jí)語(yǔ)言(High-Level Languages)
由于匯編語(yǔ)言仍然過于低級(jí),程序員需要書寫大量指令才能完成簡(jiǎn)單任務(wù)。因此,開發(fā)者創(chuàng)造了 高級(jí)語(yǔ)言,如 C、C++、Python、Java 等,使編程更加高效。
在高級(jí)語(yǔ)言中,一條指令可能對(duì)應(yīng)多條機(jī)器指令,并且采用接近自然語(yǔ)言的表達(dá)方式。例如:
sum = 17 + 20;
這行 C++ 代碼等效于上面的機(jī)器語(yǔ)言和匯編語(yǔ)言指令。高級(jí)語(yǔ)言的優(yōu)點(diǎn)包括:
- 可讀性更強(qiáng),類似人類語(yǔ)言,易于理解和學(xué)習(xí)。
- 提高編程效率,減少重復(fù)性操作,使開發(fā)者可以專注于算法和邏輯。
- 可移植性更高,可以在不同的計(jì)算機(jī)和操作系統(tǒng)上運(yùn)行,而不需要針對(duì)特定 CPU 進(jìn)行修改。
由于計(jì)算機(jī)無法直接理解高級(jí)語(yǔ)言,必須借助 編譯器(Compiler) 或 解釋器(Interpreter) 先將其轉(zhuǎn)換為機(jī)器語(yǔ)言,然后再執(zhí)行。
機(jī)器語(yǔ)言、匯編語(yǔ)言、高級(jí)語(yǔ)言對(duì)比
| 語(yǔ)言類型 | 示例 | 特點(diǎn) |
|---|---|---|
| 機(jī)器語(yǔ)言 | 1011 0000 0001 0001 |
計(jì)算機(jī)直接執(zhí)行,效率最高,但極難理解 |
| 匯編語(yǔ)言 | MOV AL, 17D |
可讀性稍強(qiáng),但仍然復(fù)雜 |
| 高級(jí)語(yǔ)言 | sum = 17 + 20; |
可讀性好,跨平臺(tái),易于編寫 |
隨著計(jì)算機(jī)技術(shù)的發(fā)展,高級(jí)語(yǔ)言成為主流,但在底層優(yōu)化、操作系統(tǒng)開發(fā)、嵌入式系統(tǒng)等領(lǐng)域,匯編語(yǔ)言仍然有一定的應(yīng)用價(jià)值。
7 編譯器、解釋器與 C++ 語(yǔ)言
高級(jí)語(yǔ)言編寫的程序在計(jì)算機(jī)執(zhí)行之前,必須轉(zhuǎn)換為機(jī)器語(yǔ)言。這種轉(zhuǎn)換方式主要有兩種:編譯(Compilation) 和 解釋(Interpretation)。
- 編譯型語(yǔ)言(Compiled Language):程序源代碼被整體翻譯為可執(zhí)行的二進(jìn)制文件,然后執(zhí)行。
- 解釋型語(yǔ)言(Interpreted Language):程序源代碼被逐行翻譯并立即執(zhí)行。
C++ 是一種 編譯型語(yǔ)言,它的源代碼必須經(jīng)過 編譯器(Compiler) 轉(zhuǎn)換為機(jī)器代碼,才能運(yùn)行。
編譯器與解釋器的區(qū)別
| 對(duì)比項(xiàng) | 編譯器(Compiler) | 解釋器(Interpreter) |
|---|---|---|
| 工作方式 | 先將整個(gè)程序翻譯成機(jī)器代碼,然后執(zhí)行 | 逐行翻譯并執(zhí)行 |
| 執(zhí)行效率 | 運(yùn)行速度快,因?yàn)橐艳D(zhuǎn)換為機(jī)器語(yǔ)言 | 運(yùn)行速度較慢,因?yàn)樾枰叿g邊執(zhí)行 |
| 錯(cuò)誤檢測(cè) | 只有在編譯時(shí)發(fā)現(xiàn)錯(cuò)誤 | 可以在執(zhí)行時(shí)逐行發(fā)現(xiàn)錯(cuò)誤 |
| 常見語(yǔ)言 | C、C++、Java(編譯為字節(jié)碼后解釋執(zhí)行) | Python、JavaScript、Shell 腳本 |
編譯型語(yǔ)言的優(yōu)勢(shì)
編譯器能對(duì)代碼進(jìn)行全局優(yōu)化,提高運(yùn)行效率。因此,C++ 在高性能計(jì)算、系統(tǒng)編程、嵌入式開發(fā)等領(lǐng)域具有廣泛應(yīng)用。相比解釋型語(yǔ)言,編譯后的 C++ 程序通常運(yùn)行更快,并且可以直接操縱硬件。
8 C++ 語(yǔ)言概述
C++ 語(yǔ)言的起源與發(fā)展
C++ 由 Bjarne Stroustrup 于 1979-1980 年 在 貝爾實(shí)驗(yàn)室(Bell Labs) 開發(fā),初衷是對(duì) C 語(yǔ)言 進(jìn)行擴(kuò)展,使其支持 面向?qū)ο缶幊蹋∣OP)。
- C++ 繼承了 C 語(yǔ)言的 高效性 和 底層控制能力,同時(shí)增加了 面向?qū)ο筇匦?/strong>(如類、繼承、多態(tài)等)。
- 由于其強(qiáng)大的性能和靈活性,C++ 可運(yùn)行在 Windows、macOS、Linux、UNIX 等多種操作系統(tǒng)上。
- 經(jīng)過多年的發(fā)展,C++ 一直是最受歡迎的編程語(yǔ)言之一,長(zhǎng)期位居 全球編程語(yǔ)言排行榜前五。
C++ 的應(yīng)用領(lǐng)域
C++ 具有高效的執(zhí)行性能和強(qiáng)大的底層操作能力,被廣泛應(yīng)用于以下領(lǐng)域:
- 操作系統(tǒng)與系統(tǒng)軟件(Windows、Linux、macOS 內(nèi)核,驅(qū)動(dòng)程序)
- 嵌入式開發(fā)(物聯(lián)網(wǎng)、汽車電子、智能家居、芯片編程)
- 游戲開發(fā)與游戲引擎(Unity、Unreal Engine、CryEngine)
- 高性能計(jì)算(人工智能、數(shù)值計(jì)算、科學(xué)模擬)
- 金融系統(tǒng)(銀行、證券、高頻交易)
- 數(shù)據(jù)庫(kù)與服務(wù)器(MySQL、PostgreSQL、Web 服務(wù)器)
- 計(jì)算機(jī)圖形學(xué)(圖像處理、3D 建模、CAD/CAM)
現(xiàn)代 C++ 的演進(jìn)
在 20 世紀(jì) 80 年代至 2000 年初,C++ 語(yǔ)言的標(biāo)準(zhǔn)化進(jìn)程較為緩慢。然而,自 2011 年 起,C++ 進(jìn)入了 現(xiàn)代 C++(Modern C++) 時(shí)代。
- C++98(1998 年):最早的 C++ 標(biāo)準(zhǔn),基于 C 語(yǔ)言,增加了面向?qū)ο筇匦浴?/li>
- C++11(2011 年):現(xiàn)代 C++ 的起點(diǎn),新增 Lambda 表達(dá)式、auto 關(guān)鍵字、智能指針、并發(fā)庫(kù) 等特性。
- C++14(2014 年):對(duì) C++11 進(jìn)行改進(jìn),增加了更簡(jiǎn)潔的語(yǔ)法和庫(kù)優(yōu)化。
-
C++17(2017 年):引入 結(jié)構(gòu)化綁定(Structured Binding)、
std::optional、并行算法 等特性。 - C++20(2020 年):大幅更新,增加 模塊化(Modules)、協(xié)程(Coroutines)、概念(Concepts) 等新功能。
如今,工業(yè)界已普遍采用 現(xiàn)代C++ 進(jìn)行開發(fā),而傳統(tǒng)的 C 語(yǔ)言風(fēng)格編程逐漸被淘汰。
為何直接學(xué)習(xí)現(xiàn)代 C++?
在高校教學(xué)中,許多課程仍然停留在 C 語(yǔ)言或 C++98 時(shí)代,導(dǎo)致學(xué)生學(xué)習(xí)的知識(shí) 落后于工業(yè)界。相比之下,直接學(xué)習(xí) C++17 或 C++20 能夠:
- 減少學(xué)習(xí)負(fù)擔(dān),避免學(xué)習(xí)過時(shí)的 C 風(fēng)格代碼。
-
掌握更現(xiàn)代、高效的編程方法(如
auto關(guān)鍵字、智能指針、Lambda 等)。 - 與工業(yè)界無縫對(duì)接,更快適應(yīng)企業(yè)開發(fā)需求。
總之,C++ 既是一門 高效、強(qiáng)大 的系統(tǒng)級(jí)編程語(yǔ)言,也是不斷演進(jìn)、與時(shí)俱進(jìn)的現(xiàn)代化語(yǔ)言。學(xué)習(xí) 現(xiàn)代 C++,才能真正發(fā)揮 C++ 的優(yōu)勢(shì),適應(yīng)當(dāng)前的技術(shù)趨勢(shì)。
9 C++ 程序開發(fā)步驟
與其他編程語(yǔ)言類似,使用 C++ 編寫程序也需要遵循一定的步驟。這個(gè)過程包括以下幾個(gè)主要階段:
-
理解問題
首先,需要清楚地理解所面臨的問題。關(guān)鍵問題包括:- 輸入:程序需要哪些數(shù)據(jù)?這些數(shù)據(jù)從哪里來?(如鍵盤、文件等)
- 輸出:程序?qū)⑤敵鍪裁唇Y(jié)果?該結(jié)果如何顯示或保存?(如屏幕顯示、保存到文件等)
-
提出算法
根據(jù)問題描述,設(shè)計(jì)出解決問題的步驟和邏輯。算法是用來描述如何解決問題的指令序列,通常用偽代碼或流程圖來表示。 -
編寫程序
將算法轉(zhuǎn)化為 C++ 代碼。通過編程語(yǔ)言的語(yǔ)法和規(guī)則,將算法實(shí)現(xiàn)為可執(zhí)行的程序。 -
測(cè)試
通過不同的測(cè)試用例驗(yàn)證程序的正確性。測(cè)試時(shí),除了使用有效數(shù)據(jù)進(jìn)行驗(yàn)證外,還要考慮非法輸入的情況,查看程序是否能夠正確處理錯(cuò)誤。
舉例:計(jì)算一組數(shù)值的平均值
假設(shè)我們要編寫一個(gè)程序來計(jì)算一組數(shù)值的平均值,以下是整個(gè)開發(fā)流程的實(shí)例:
-
理解問題
- 輸入:這些數(shù)值從哪里來?用戶是通過鍵盤輸入,還是從文件中讀???
- 輸出:程序計(jì)算出來的平均值是如何呈現(xiàn)的?是打印在屏幕上,還是保存到文件中?
-
提出算法
算法的核心思想是:- 初始化兩個(gè)變量,一個(gè)用于存儲(chǔ)總和,另一個(gè)用于計(jì)數(shù)。
- 循環(huán)讀取每一個(gè)數(shù)值,將其加到總和中,并增加計(jì)數(shù)器。
- 最后,用總和除以計(jì)數(shù)器,得到平均值。
偽代碼示例:
-----------start------------- 總和 sum = 0 計(jì)數(shù)器 count = 0 重復(fù): 讀入一個(gè)數(shù)值 如果讀取失敗,結(jié)束循環(huán) 否則: 將讀取的數(shù)值加到總和 sum 計(jì)數(shù)器 count 增加 1 計(jì)算平均值:average = sum / count 輸出/打印平均值 average -----------end------------- -
編寫程序
根據(jù)上述算法,使用 C++ 語(yǔ)言將其實(shí)現(xiàn)為程序:#include <iostream> using namespace std; int main() { double sum = 0; // 總和 int count = 0; // 計(jì)數(shù)器 double value; // 輸入的數(shù)值 while (cin >> value) { sum += value; count++; } if (count > 0) { double average = sum / count; cout << "平均值為: " << average << endl; } else { cout << "沒有輸入有效的數(shù)值!" << endl; } return 0; } -
測(cè)試
運(yùn)行程序時(shí),輸入不同的測(cè)試數(shù)據(jù),確保其輸出結(jié)果正確。- 正常情況:輸入一系列數(shù)字,程序計(jì)算并輸出正確的平均值。
- 邊界情況:沒有輸入任何數(shù)值時(shí),程序應(yīng)該提示用戶沒有有效數(shù)據(jù)輸入。
- 非法輸入:輸入非數(shù)值數(shù)據(jù)(如字符串或特殊字符),程序應(yīng)當(dāng)能夠適當(dāng)?shù)靥幚礤e(cuò)誤或提示。
示例測(cè)試輸入:
10 20 30輸出結(jié)果:
平均值為: 20
通過這種方法,我們可以從理解問題、設(shè)計(jì)算法、編寫程序,到最終的測(cè)試,逐步完成一個(gè) C++ 程序的開發(fā)過程。