---
# System prepended metadata

title: 無所不在的C++ - 新手村
tags: [程式設計, cpp]

---

無所不在的C++ - 新手村
===
###### tags: `程式設計` `cpp`
:::success
🤖 本篇由 [**chatGPT**](https://platform.openai.com/) 及 [**Mai.Coding**](https://hackmd.io/@0x0607) 共同彙整
目前不考慮出第二篇，統整資料好累
:::
# **認識C++**
:::info
💡 介紹一些關於C++的故事及特色
:::
## **C++歷史**
* **C++** 最早是由 Bjarne Stroustrup 於 **1983** 年開發的，當時其名為 **C with Classes**。
* **1985 年**，Bjarne Stroustrup 將 **C with Classes** 重新命名為 **C++**，並在同年發布了第一個 **C++** 版本。
* **C++** 廣泛應用於**系統軟體**、**桌面應用程式**以及**遊戲開發等方面**。

## **C++語言特性**
* **物件導向**：C++ 語言支援物件導向設計，可以將相關的變數和函式封裝在一個物件中。
* **封裝 (Encapsulation)**：可以將成員變數和成員函式封裝在一個類中，只提供必要的接口給外部。
* **繼承 (Inheritance)**：子類可以繼承父類的屬性和方法。
* **多型 (Polymorphism)**：同一個函式可以被不同的子類實現，並且可以按照類型自動選擇合適的實現方式。

## **C++程式類型**
* **C++ Application**：獨立運行在電腦上的 C++ 程式。
* **C++ Library**：可以被其他 C++ 程式引用的庫文件。
* **Driver：驅動程式**，用於控制硬體設備。
* **Kernel**：核心程式，用於管理電腦資源和運行其他程式。

## **C++開發環境**
* **IDE**：如 Microsoft Visual Studio、CodeLite、Xcode。
* **編譯器**：如 Microsoft Visual C++、GNU GCC。
* **編輯器**：如 Notepad++、Vim、Emacs。

## **其他關於C++知識**
### **高效能**
C++ 被稱為高效能的程式語言，因為其原始碼可以直接編譯成機器語言，
運行**速度快**，**佔用資源少**，且通常比其他高階語言更適合系統軟體和遊戲開發等場合。
### **開發流程**
C++ 的開發流程通常包括項目**規劃**、**設計**和**實現**、**測試**和**調試**以及**部署**和**維護**等階段。
在每個階段都需要開發人員進行經驗和技能的分工協作，以確保最終產品的品質和效率。
### **庫文件**
C++ 語言有許多可以重用代碼的庫文件，可以大大簡化開發人員的工作，
常見的庫文件有**標準庫**、**系統庫**、**框架庫**、**第三方庫**等等。
### **跨平台**
C++ 語言在原始碼級別上具有跨平台特性，但也因此需要特別注意程式碼的可移植性，
以適應不同的操作系統和硬件環境。

# **變數(Variables)**
:::info
變數是儲存資料的單位，每個變數都有各自的名稱與資料型態。
在 C++ 中，變數必須先宣告才能使用。
:::

## **變數宣告(Declaration)**

變數宣告的目的是告知電腦，程式中要使用哪些變數，並配置記憶體以供存放。
變數必須在第一次使用前宣告。

變數宣告的語法如下：
```cpp=
DataType VarName [= Initial Value];
```
- **DataType**：變數的資料型態，例如 `int`、`double` 等。
- **VarName**：變數的名稱，可以是任何合法的識別字，建議使用有意義的名稱。
- **Initial Value**：變數的初始值，可以省略不寫。
  如果省略不寫，則變數的初始值為 `0`（數值類型）或 `null`（物件類型）。

以下是一個變數宣告的範例：
```cpp=
int a = 24;
double b;
```

在這個範例中，我們宣告了兩個變數 `a` 和 `b`。
`a` 的資料型態為 `int`，初始值為 `24`。
`b` 的資料型態為 `double`，沒有初始值。

## **變數命名規則**

在 C++ 中，變數的命名規則如下：

- 變數名稱必須以`字母`或`底線`開頭。
- 變數名稱不能以`數字`開頭。
- 變數名稱只能包含`字母`、`數字`或`底線`。
- 變數名稱不能是 C++ 的關鍵字（例如 `int`、`double` 等）。

## **資料型態**

以下這些基本資料型態是 C++ 語言中最基本的資料型態，用來儲存各種不同的資料。
在宣告變數時，**必須**指定變數的**資料型態**。

### **整數型態**
在 C++ 中，整數型態用來儲存整數，包括`正整數`、`負整數`和`零`。整數型態在不同的系統和編譯器中可能大小不同，但通常包括 `char`、`short`、`int` 和 `long` 四種。

| 資料型態 | 描述 | 長度（位元組） | 範圍 |
| --- | --- | --- | --- |
| **short** | `16` 位元的`有符號整數` | 2 | `-32,768` 到 `32,767` |
| **int** | `32` 位元的`有符號整數` | 4 |`-2,147,483,648` 到 `2,147,483,647` |
| **long** | `64` 位元的`有符號整數` | 8 | `-9,223,372,036,854,775,808` 到 `9,223,372,036,854,775,807` |

宣告範本：
```c
short s = 88;
int i = 88;
long l = 88L;
```

### **浮點型態**
在 C++ 中，浮點型態用來儲存浮點數，包括`正數`、`負數`和`零`。浮點型態在不同的系統和編譯器中可能大小不同，但通常包括 `float` 和 `double` 兩種。

| 資料型態 | 描述 | 長度（位元組） | 範圍 |
| --- | --- | --- | --- |
| **float** | `單精度浮點數` | 4 | 可儲存 `6` 個有效位數 |
| **double** | `雙精度浮點數` | 8 | 可儲存 `15` 個有效位數 |

宣告範本：
```c
float f = 3.141f;
double d = 3.141;
```

### **字元型態**
在 C++ 中，字元型態用來儲存單個字符，包括`字母`、`數字`、`符號`和`控制字符`。字元型態為 `char`。

宣告範本：
```c
char c = 'a';
```

### **字串型態**
在 C++ 中，字串型態用來儲存一序列的字元，類型為 `string`。字串是以雙引號或單引號表示的，透過這個型態來儲存**任意長度**的文字。

宣告範本：
```cpp
string s = "Hello World!";
```
:::spoiler
:::info
值得注意的是`string`這個型態在C語言中是**沒有**的，而C語言則是使用`字元陣列`來處理字串
:::

### **布林型態**
C 語言中**沒有**內建的布林型態，通常可以使用 `int` 來儲存布林值，
`0` 代表 `false`，非 `0` 值代表 `true`。

宣告範本：
```c
int b = 1;
``` 

## **溢位(Overflow)**
溢位是一種當數值超過資料型態範圍的錯誤。在 C++ 中，每種資料型態都有其範圍限制，如果資料型態無法容納某個數值，則會發生溢位錯誤。溢位錯誤可能會導致程式產生不正確的結果，因此在實際開發中應該避免使用可能導致溢位的操作。

以下是各種資料型態的範例程式，用來示範溢位錯誤：
```c
// char 溢位
char c = 127;
c++;
std::cout << c << std::endl;  // -128

// short 溢位
short s = 32767;
s++;
std::cout << s << std::endl;  // -32768

// int 溢位
int i = 2147483647;
i++;
std::cout << i << std::endl;  // -2147483648

// long 溢位
long l = 9223372036854775807L;
l++;
std::cout << l << std::endl;  // -9223372036854775808

// float 溢位
float f = __FLT_MAX__;
f *= 2;
std::cout << f << std::endl;  // inf

// double 溢位
double d = __DBL_MAX__;
d *= 2;
std::cout << d << std::endl;  // inf
```

在這些範例中，我們使用了各種資料型態的最大值，然後將其加上 `1` 或乘以 `2`，以引發溢位錯誤。
當發生溢位時，資料型態的值會從最大值變成最小值，或從最小值變成最大值，因此會產生不正確的結果。
在實際開發中，我們應該避免使用可能導致溢位的操作，以確保程式的正確性。

## **常數(constant)**
在 C++ 中，我們可以使用 `const` 來聲明常數，它指向的變數是**不可改變**的。
一旦使用 `const` 關鍵字聲明了一個變數，其值就不可再更改。

定義一個常數的語法如下：
```cpp
const DataType VarName = InitialValue;
```


`DataType` 是指變數的資料型別。
`VarName` 是變數的名稱。
`InitialValue` 是變數的初始值。

以下是一個常數的範例：
```cpp
const double PI = 3.1415;
```
:::info
在這個範例中，`PI` 被聲明為一個常數，其值為 `3.1415`。
由於 `PI` 是一個常數，所以在程式執行過程中其值不會改變。
:::

如果在程式碼中試圖更改 PI 的值，例如：
```cpp
const double PI = 3.1415;
PI = 5.4321;
```
:::danger
則會在編譯時期產生錯誤。
:::

需要補充的是，C++ 中的常數通常使用全部大寫字母表示，並使用底線分隔單詞，例如 `CURRENT_USER_NUM`。
此外，常數的命名應該具有**描述性**，以便於程式碼的閱讀和理解。

# **運算子(Operator)**
:::info
運算子是在程式語言中用來執行特定操作的符號或關鍵字，
例如數學運算、邏輯運算、位元運算等。
每一種運算子都有其特定的功能和用法，並且可以應用在不同的資料型別上。
:::

## **類型**
C++ 中的運算子可對一個、兩個或三個運算元執行動作。
依照所需運算元數目，運算子可分為以下**三種**：

* **一元運算子**：只需要**一**個運算元，對變數進行**遞增/遞減**操作，
    例如 `++a`、`--a`。
* **二元運算子**：需要**兩**個運算元，將**右邊**的運算元**賦值**給**左邊**的運算元，
    例如 `a = 99`。
* **三元運算子**：需要**三**個運算元，語法為 `condition ? expression1 : expression2`，
    其中 `condition` 為條件，如果條件成立，則回傳 expression1 的值，
    否則回傳 `expression2` 的值，例如 `(a>0) ? a-1 : (a+1)`。

另外，許多二元運算子都可以分成**算術運算子**、**關係運算子**和**邏輯運算子**這三種大類。

依照運算子擺放位置，運算子可分為以下**三種**：

**前置運算子**：運算子擺放在運算元之**前**，例如 `++a`。
**後置運算子**：運算子擺放在運算元之**後**，例如 `a++`。
**中置運算子**：運算子擺放在**中間**，例如 `a + b`。

### **算術運算子**
#### **單一運算子**
| 運算子 | 用法 | 說明 |
| --- | --- | --- |
| + | +a | 表示正 a |
| - | -a | 表示負 a |
| ! | !a | 表示邏輯非，將 a 的值取反 |
| ~ | ~a | 表示位元反轉，將 a 的二進位表示法的每個位元取反 |
| ++ | a++ 或 ++a | 表示將 a 的值加 1，若放在 a 的後面則先回傳 a 的值再加 1，若放在 a 的前面則先加 1 再回傳 a 的值 |
| -- | a-- 或 --a | 表示將 a 的值減 1，若放在 a 的後面則先回傳 a 的值再減 1，若放在 a 的前面則先減 1 再回傳 a 的值 |
#### **二元運算子**
| 運算子 | 用法 | 說明 |
| --- | --- | --- |
| + | a + b | a 加上 b |
| - | a - b | a 減去 b |
| * | a * b | a 乘上 b |
| / | a / b | a 除以 b |
| % | a % b | a 除以 b 的餘數 |
### **指定運算子**
| 運算子 | 用法 | 說明 |
| --- | --- | --- |
| = | a = b | 將 b 的值賦給 a |
| += | a += b | 將 a 加上 b 的值後再賦給 a |
| -= | a -= b | 將 a 減去 b 的值後再賦給 a |
| \*= | a \*= b | 將 a 乘上 b 的值後再賦給 a |
| /= | a /= b | 將 a 除以 b 的值後再賦給 a |
| %= | a %= b | 將 a 除以 b 的餘數再賦給 a |
### **關係運算子**
| 運算子 | 用法 | 說明 |
| --- | --- | --- |
| == | a == b | 判斷 a 是否等於 b，若成立則回傳 true，否則回傳 false |
| != | a != b | 判斷 a 是否不等於 b，若成立則回傳 true，否則回傳 false |
| < | a < b | 判斷 a 是否小於 b，若成立則回傳 true，否則回傳 false |
| <= | a <= b | 判斷 a 是否小於等於 b，若成立則回傳 true，否則回傳 false |
| > | a > b | 判斷 a 是否大於 b，若成立則回傳 true，否則回傳 false |
| >= | a >= b | 判斷 a 是否大於等於 b，若成立則回傳 true，否則回傳 false |
### **條件運算子**
| 運算子 | 用法 | 說明 |
| --- | --- | --- |
| && | a && b | 邏輯 AND，若 a 和 b 都成立則回傳 true，否則回傳 false |
| \|\| | a \|\| b | 邏輯 OR，若 a 或 b 有一個成立則回傳 true，否則回傳 false |
### **邏輯運算子** 
| 運算子 | 用法 | 說明 |
| --- | --- | --- |
| ! | !a | 表示邏輯非，將 a 的布林值取反 |
| & | a & b | 位元 AND，將 a 和 b 的二進位表示法進行 AND 運算 |
| \| | a \| b | 位元 OR，將 a 和 b 的二進位表示法進行 OR 運算 |
| ^ | a ^ b | 位元 XOR，將 a 和 b 的二進位表示法進行 XOR 運算 |
### **位元運算子**
| 運算子 | 用法 | 說明 |
| --- | --- | --- |
| << | a << b | 左位移，將 a 的二進位表示法向左移動 b 個位元 |
| >> | a >> b | 右位移，將 a 的二進位表示法向右移動 b 個位元 |
| ~ | ~a | 取補數，將 a 的二進位表示法進行 NOT 運算 |
| & | a & b | 二進位 AND，將 a 和 b 的二進位表示法進行 AND 運算 |
| \| | a \| b | 二進位 OR，將 a 和 b 的二進位表示法進行 OR 運算 |
| ^ | a ^ b | 二進位 XOR，將 a 和 b 的二進位表示法進行 XOR 運算 |
### **進階指定運算子**
| 運算子 | 用法 | 說明 |
| --- | --- | --- |
| &= | a &= b | 將 a 和 b 的二進位表示法進行 AND 運算後再賦給 a |
| \|= | a \|= b | 將 a 和 b 的二進位表示法進行 OR 運算後再賦給 a |
| ^= | a ^= b | 將 a 和 b 的二進位表示法進行 XOR 運算後再賦給 a |
| <<= | a <<= b | 將 a 的二進位表示法向左移動 b 個位元後再賦給 a |
| >>= | a >>= b | 將 a 的二進位表示法向右移動 b 個位元後再賦給 a |
| &= | a &= b | 將 a 和 b 的二進位表示法進行 AND 運算後再賦給 a |
| \|= | a \|= b | 將 a 和 b 的二進位表示法進行 OR 運算後再賦給 a |
| ^= | a ^= b | 將 a 和 b 的二進位表示法進行 XOR 運算後再賦給 a |
| <<= | a <<= b | 將 a 的二進位表示法向左移動 b 個位元後再賦給 a |
| >>= | a >>= b | 將 a 的二進位表示法向右移動 b 個位元後再賦給 a |

# **程式區塊 (Blocks)**
:::info
程式區塊是以 `{}` 大括號包覆而成，可以內含零個或以上的敘述。
通常在條件判斷語句中使用，例如 if 判斷句，若條件成立，就會執行 `{}` 內包含的敘述，否則略過。
在許多程式語言中，程式區塊還會配合分號 `;` 結束敘述，確保程式碼的正確執行。
:::

範例：
```cpp=
if (a > 2) {
    // 如果 a 大於 2，則執行以下程式區塊內的敘述
    cout << "a is greater than 2." << endl;
} else {
    // 如果 a 小於等於 2，則執行以下程式區塊內的敘述
    cout << "a is less than or equal to 2." << endl;
}
```

在程式區塊的 `{}` 內也可以包含其他的程式區塊，例如**多層迴圈**、**巢狀**的**if 判斷**等等，只要在不同層次的程式區塊中使用不同的變數名稱，即可避免變數名稱衝突的問題。

# **程式流程(Program-flow)**
:::info
程式可以使用結構化的方式來表達流程，讓程式碼更易讀、易維護
:::
## **循序結構**
循序結構是程式中最簡單的結構之一，它**按照順序執行敘述**，從上到下按照程式碼的順序執行，沒有任何的分支或迴圈。

以下是一個簡單的 C++ 程式碼示例：
```cpp=
int a = 1;
int b = 2;
int c = a + b;
cout << c;
```


## **選擇結構**
選擇結構基於條件來決定程式的執行路徑，當條件滿足時執行 `A 敘述`，否則執行 `B 敘述`。

下面是一個簡單的 `if-else` 選擇結構的例子：
```cpp=
int x = 5;
if (x > 0) {
    cout << "x 是一個正數";
} else {
    cout << "x 不是一個正數";
}
```

## **重複結構**
重複結構可以讓程式重複執行某些敘述，以達到簡化程式碼的目的。

以下是一個簡單的 `while` 迴圈重複結構的例子：
```cpp=
int i = 0;
while (i < 9) {
    cout << i;
    i++;
}
```

此迴圈會進行 `5` 次迴圈，每次迴圈都會把目前的數字印出來，直到迴圈次數到達 `5` 次為止。

# **基本語法(Basic)**
:::info
💡 開始寫程式囉
:::

## **if-else和switch**
`if-else` 和 `switch` 都是在程式中用來進行條件判斷的關鍵字。

### **if-else**
`if-else` 在條件成立時執行一段程式碼，反之則執行另外一段程式碼。
```cpp=
if (score >= 60) {
    cout << "pass" << endl;
} 
else {
    cout << "fail" << endl;
}
```

## **switch**
`switch`可以根據變數的值執行對應的程式碼。
```cpp=
switch (keyCode) {
    case 37:
        moveLeft();
        break;
    case 38:
        moveUp();
        break;
    case 39:
        moveRight();
        break;
    case 40:
        moveDown();
        break;
    default:
        cout << "invalid key" << endl;
        break;
}
```

## **輸入(Input)**
在C++中，使用`cin`來接收使用者的輸入。
使用時需先引入`<iostream>`標頭檔。
    
```cpp=
#include <iostream>
using namespace std;

int main() {
    int num;
    cout << "請輸入一個整數：";
    cin >> num;
    cout << "你輸入的整數是：" << num << endl;
    return 0;
}
```
在上面的程式碼中，我們先宣告一個整數變數`num`。
然後使用`cout`輸出提示使用者輸入的訊息。
接下來使用`cin`來接收使用者輸入的整數，
並將其賦值給`num`變數。

## **輸出(Output)**
在C++中，你可以使用`cout`來輸出訊息到控制台上。
```cpp=
#include <iostream>
using namespace std;

int main() {
    cout << "Hello, World!" << endl;
    return 0;
}
```
輸出結果：
```bash
Hello, World!
```


`cou`t是標準輸出流，是C++中最常用的輸出方法之一。
它可以幫助你將訊息輸出到控制台上，而`endl`可以輸出**換行符號**，使輸出結果更加美觀。