National Taiwan University
Uedu Main Site
Explore Uedu
Student Console
Register as Member/Login
Research Informed Consent Center
Survey Center
Educational Big Data Challenge
Claim or create a course
Try a Scenario Task
Support & Messages
Uptime Data

UeduGPTs

--

Jupyters

2

Local AI

--

Uedu Code

--

台灣大學 AQI 70 24°C PM2.5 17
AI Reply Desktop Notifications

Show a desktop notification when the AI TA finishes replying

Chat Message Notifications

Notify me when classmates post messages in the forum

Sound notification

Play an alert sound whenever there is a new notification

Unit 01

C++ 簡介

C++ 的歷史與特點、第一個程式、從原始碼到執行檔
Interaction實作導覽 15 minute(s)

Learning Objectives

  • 說出 C++ 從 C with Classes 發展而來的經過,以及 C++98 到 C++23 的標準版本
  • 說明 C++ 的特點:編譯式、靜態型別、效能與直接控制記憶體、支援多種程式設計風格
  • 舉例說明 C++ 常見的應用領域
  • 逐行讀懂第一個 C++ 程式:#include、using namespace std、main、cout、return 0
  • 說明原始碼變成執行檔的四個階段,並用 g++ 編譯、執行程式

為什麼要學 C++

你每天用的瀏覽器、玩的遊戲、電腦的作業系統,裡面都有大量以 C++ 寫成的程式。 C++ 能寫出執行很快、佔用資源少的程式,也讓你直接控制記憶體;代價是寫程式時要多注意細節,例如每個變數的型別、記憶體什麼時候釋放。

學 C++ 的收穫不只是一個語言:你會看見程式在電腦裡實際怎麼運作,變數放在哪裡、資料佔幾個位元組、函式呼叫時發生什麼事。 這些觀念學會之後,再看其他語言也會更清楚。

這一課先認識 C++ 的來歷與特點,再讀懂第一個程式,最後看原始碼怎麼變成可以執行的程式。

從 C 到 C++

C++ 的設計者是 Bjarne Stroustrup。他在 1979 年於 AT&T 貝爾實驗室(Bell Labs)開始這項工作, 想用 Simula 語言那種「類別」的方式來組織程式,同時保有 C 語言的執行效率,所以最早的版本叫做 C with Classes(有類別的 C)。

1983 年 C with Classes 改名為 C++,名字是同事 Rick Mascitti 提議的。++ 是 C 語言的遞增運算子(x++ 表示 x 加 1), C++ 的意思就是「C 的下一步」。1985 年 10 月,第一個商業版本與 Stroustrup 的著作《The C++ Programming Language》第一版同時推出。

之後 C++ 由國際標準組織(ISO)制定標準,各家編譯器依照同一份標準實作:

版本 年份 說明
C++98 1998 第一個 ISO 標準(ISO/IEC 14882:1998)
C++03 2003 修正 C++98 的問題
C++11 2011 大幅更新:auto、範圍 for 迴圈、lambda、nullptr、智慧指標、多執行緒函式庫等
C++14、C++17、C++20 2014、2017、2020 之後大約每三年發布一版
C++23 2023 目前的標準,ISO 在 2024 年 10 月正式出版(ISO/IEC 14882:2024)

下一版 C++26 正在制定中。從 C++11 開始的寫法常被稱為「現代 C++」。CodeLab 的 C++ 課程以 C++17 為準, 你在網路上看到的舊範例如果寫法和這裡不同,多半是因為它還停在 C++98 的寫法。

C++ 的特點

特點 意思
編譯式語言 原始碼先由編譯器整個翻譯成機器碼,產生執行檔;執行時不需要原始碼,也不需要編譯器
靜態型別 每個變數宣告時就決定型別(int、double…),之後不能改;型別不合,編譯時就會報錯
效能與直接控制記憶體 可以取得變數的位址、自己配置與釋放記憶體,適合需要精準控制速度與資源的程式
支援多種寫法 可以像 C 一樣用函式一步一步寫(程序式),也可以用類別與物件(物件導向),還可以用模板寫出適用多種型別的程式(泛型程式設計)

如果你學過 Python,可以這樣對照:

int count = 3;        // C++:先宣告型別 int,每一句以分號結尾
count = "three";      // 編譯錯誤:int 不能放字串

Python 的 count = 3 不用寫型別,執行到那一行才知道 count 是什麼;C++ 在編譯時就檢查型別, 錯誤會在程式執行之前被抓出來。

C++ 用在哪裡

C++ 適合「執行速度要快、要直接操作硬體或大量資料」的場合。以下例子都有公開資料可以查:

領域 例子
作業系統 Microsoft 的 Windows 等產品大量使用 C++;macOS 的部分重要元件也是 C++
瀏覽器 Google Chrome 的開源基礎 Chromium、Mozilla Firefox
遊戲引擎 Unreal Engine 以 C++ 撰寫遊戲邏輯;許多遊戲公司的引擎與物理模擬元件
資料庫 MySQL Server
編譯器與開發工具 GCC、LLVM 與 Clang 本身就是用 C++ 寫的
嵌入式與即時控制 船用柴油引擎控制、飛機的任務軟體等,對反應時間有嚴格要求的系統
科學與高效能運算 CERN 的資料分析工具 ROOT、粒子模擬工具 Geant4,以及 NASA 火星探測車的自主導航系統

這些系統很少只用一種語言,例如 Firefox 也有 JavaScript 與 Rust 的程式碼;但效能最關鍵的部分常常交給 C++。

第一個 C++ 程式

按「下一步」一句一句執行。注意程式不是從第 1 行開始跑:第 1~3 行是給編譯器看的,執行是從 main 開始。每執行一句 cout,下方的輸出區就多一行字。

逐行讀懂第一個程式

程式 意思
// 第一個 C++ 程式… 註解:// 之後到行尾都會被編譯器略過,只寫給人看。多行註解用 /* … */
#include <iostream> 把標準函式庫的 iostream(輸入輸出)引入,才能使用 cout、cin。# 開頭的是前置處理指令,結尾不加分號
using namespace std; 標準函式庫的名稱都放在 std 這個命名空間裡。寫了這行,std::cout 就可以簡寫成 cout
int main() { … } main 函式:每個 C++ 程式都必須有一個,程式從這裡開始執行。int 表示它結束時會回傳一個整數
cout << "Hello, C++!" << endl; cout 是輸出到螢幕的物件,<< 把右邊的資料送過去,可以一直串接;endl 代表換行
return 0; 結束 main,把 0 回傳給作業系統,0 表示「正常結束」

幾個一開始就要養成的習慣:

  • 每一句(陳述式)以分號 ; 結尾;忘了寫是初學最常見的編譯錯誤
  • 大括號 { } 把同一個區塊的程式包起來,裡面的程式縮排 4 格,方便閱讀
  • C++ 區分大小寫:Main、COUT 和 main、cout 是不同的名稱
  • main 最後的 return 0; 可以省略(標準規定 main 執行到結尾時視同回傳 0),但其他回傳 int 的函式不能省略

using namespace std; 在小程式裡很方便,CodeLab 的範例大多會寫。大型專案常改寫成 std::cout, 避免自己取的名稱和標準函式庫撞名。下一個範例就是不寫這行的版本。

由上而下執行、std:: 與註解

這個程式沒有 using namespace std;,所以每個 cout、endl 前面都加上 std::。注意第 5~6 行的多行註解,執行時直接被跳過;第 9 行沒有 endl,所以下一句的輸出會接在同一行。

程式從 main 開始

greet 寫在 main 前面,但程式還是從 main 開始執行。第 11 行呼叫 greet() 時,右邊多出一個 greet 的框架,執行完它的內容後回到 main。greet 被呼叫兩次,就執行兩次。

想一想:C++ 的來歷與特點

1.

C++ 在 1983 年改名之前叫做什麼?

2.

C++ 名稱裡的 ++ 代表什麼?

3.

說 C++ 是「編譯式、靜態型別」的語言,下列哪一個描述正確?

第 1 次作答

從原始碼到執行檔

電腦的處理器只看得懂機器碼,hello.cpp 這種文字檔不能直接執行。用 g++ 編譯時,會依序經過四個階段:

階段 做什麼 產生的檔案
1. 前置處理(preprocessing) 處理 # 開頭的指令:把 #include 的標頭檔內容整個貼進來、刪掉註解 .ii(展開後的原始碼)
2. 編譯(compilation) 檢查語法與型別,把 C++ 翻譯成組合語言 .s(組合語言)
3. 組譯(assembly) 把組合語言轉成機器碼 .o(目的檔,object file)
4. 連結(linking) 把目的檔和標準函式庫(例如 cout 的實作)接在一起 執行檔

平常只要下一個指令 g++ hello.cpp -o hello,g++ 就會自動跑完四個階段,中間檔案不會留下來。 語法錯誤會在第 2 階段被發現;如果用了某個函式卻找不到它的實作,錯誤會在第 4 階段(連結)出現。

本頁的逐步執行動畫是 CodeLab 的直譯器在瀏覽器裡模擬執行,方便你看見每一步。真正的 C++ 程式要先經過上面的編譯流程。

用 g++ 編譯與執行

以下是在 Linux(Ubuntu)終端機的操作。Ubuntu 可以用 sudo apt install g++ 安裝 g++;Windows 可以在 WSL 裡的 Ubuntu 操作,指令相同。

  1. 1

    確認有 g++,看一下原始碼

    which g++ 會顯示 g++ 安裝在哪裡;沒有任何輸出代表還沒安裝。cat 把檔案內容印出來,這就是剛才的第一個程式。

  2. 2

    一個指令編譯,再執行

    -o hello 指定執行檔的名稱,不寫的話會叫 a.out。-std=c++17 指定用 C++17 標準編譯(g++ 不指定時的預設標準依版本而不同),-Wall 開啟常見的警告,建議每次都加上。編譯成功時 g++ 不會印出任何東西。執行檔要寫成 ./hello,表示「目前資料夾裡的 hello」。

  3. 3

    把四個階段拆開來跑

    -E 只做前置處理,-S 做到產生組合語言為止,-c 做到產生目的檔為止,最後不加這些選項就會連結出執行檔。打開 hello.ii 會發現它有好幾萬行:#include <iostream> 把整個標頭檔都貼進來了。

  4. 4

    編譯錯誤長什麼樣子

    hello_typo.cpp 是把第 6 行結尾的分號刪掉的版本。g++ 的錯誤訊息格式是「檔名:行:欄: error: 說明」,這裡說的是「在 cout 之前應該有分號」:缺分號時,編譯器要讀到下一行開頭才發現不對,所以要往前一行找。錯誤訊息後面還會印出那一行程式,並用符號標出位置(以「…」省略)。編譯失敗不會產生執行檔;echo $? 顯示上一個指令的結束狀態,不是 0 就代表失敗。

這段導覽完成了

想一想:程式與編譯

1.

下面的程式會印出什麼?

#include <iostream>
using namespace std;

int main() {
    cout << "2 * 5 = " << 2 * 5;
    return 0;
}
2.

下面的程式執行結果是什麼?

#include <iostream>

int main() {
    cout << "Hi" << std::endl;
    return 0;
}
3.

程式呼叫了一個函式,原始碼語法都正確,但這個函式的實作不存在。g++ 會在哪個階段報錯?

第 1 次作答

動手寫:自我介紹

完成 main,讓程式印出下面三行。第三行的 21 要用 3 * 7 讓程式算出來,不要直接寫 21。

姓名:王小明
科系:資訊管理學系
3 x 7 = 21
你的輸出
預期輸出

重點回顧

  • C++ 由 Bjarne Stroustrup 在 1979 年開始設計,最早叫 C with Classes,1983 年改名 C++;++ 是 C 的遞增運算子
  • 第一個 ISO 標準是 C++98,C++11 是一次大幅更新,之後約每三年一版,目前是 C++23;本課程以 C++17 為準
  • C++ 是編譯式、靜態型別的語言,執行效率高、可以直接控制記憶體,支援程序式、物件導向與泛型等寫法
  • 作業系統、瀏覽器、遊戲引擎、資料庫、編譯器、嵌入式系統與科學運算都大量使用 C++
  • 程式從 main 開始執行;#include <iostream> 才能用 cout;每一句以分號結尾;C++ 區分大小寫
  • 原始碼經過前置處理、編譯、組譯、連結四個階段變成執行檔;g++ -std=c++17 -Wall hello.cpp -o hello 一次完成
這一課完成了!
Next lesson:基本輸入輸出
你目前沒有登入,學習進度只存在這個瀏覽器。 Login 後,進度會跟著帳號,換電腦也看得到。