<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>http://localhost:3000</id>
    <title>個人部落格</title>
    <updated>2026-06-17T13:02:16.641Z</updated>
    <generator>Next.js Blog Generator</generator>
    <link rel="alternate" href="http://localhost:3000"/>
    <subtitle>使用 Next.js 和 Markdown 打造的極簡風格個人寫作空間</subtitle>
    <icon>http://localhost:3000/favicon.ico</icon>
    <rights>© 2026 All rights reserved.</rights>
    <entry>
        <title type="html"><![CDATA[每天寫文章的起點]]></title>
        <id>http://localhost:3000/blog/2026_06_17</id>
        <link href="http://localhost:3000/blog/2026_06_17"/>
        <updated>2026-06-17T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[希望我每天都會寫文章]]></summary>
        <content type="html"><![CDATA[
## Update 日常
歐歐歐最近有點太幸運了

上了中興資管，原本還以為沒有機會了

備取4上，不用留在嘉義吃四年的雞肉飯

在畢聯會認識好多朋友

也找到幾個可以出去玩的好朋友超開心

畢聯會心得就有空再寫吧

我也有點懶惰

但我會逼自己每天紀錄和寫文章的

希望我可以寫超過一年(而且還不用AI寫哈哈哈哈)

去看了後室 好這個也要記的寫心得

然侯股票可以繼續漲嗎

||~~什麼時候讓我的股票部位超過50個W~~||

(不要看 我亂講的 我連10w都沒有啦)

喔喔喔我的畢業貼文還沒Po

明明很多時間嗎(?

我努力 最近在社群上花的時間蠻少的

期待去台中玩，還有下個月的台南局(非常期待)

都沒有emoji是為什麼，因為windows打emoji小麻煩

之後會加一點的

保齡球還是很爛

我以為長大會好一點超好笑

6/18之後要上微積分(危機分) 

7/18考試、8月考試(希望會過啦 直接免修)

好 最後愛大家 最近一起出去玩的朋友們

愛您🫰🫰🫰 上大學還是要約 不要忘記彼此

阿誰先賺大錢 誰就請客]]></content>
        <author>
            <name>作者名稱</name>
        </author>
        <category label="日記"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[F1 Movie 影評]]></title>
        <id>http://localhost:3000/blog/F1_movie_Review</id>
        <link href="http://localhost:3000/blog/F1_movie_Review"/>
        <updated>2025-07-13T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[本文介紹觀賞 F1 Movie 後的劇情、心得感想、拍攝技巧、實際場地、電影中事件與現實。]]></summary>
        <content type="html"><![CDATA[
![F1 movie劇照](/images/f1_movie_pic3.jpg)

## 劇情(無爆雷版本)
> 有含爆雷完整版想看可以往下滑

《F1》是一部以一級方程式(Formula 1)為背景的劇情片，講述1990年代天才車手桑尼·海耶斯（布拉德·彼特飾）的復出故事。桑尼曾是F1的明日之星，但一場嚴重事故終結了他的職業生涯，迫使他退出賽壇，過著遊牧賽車手的生活。三十年後，桑尼的舊友、APXGP車隊老闆魯賓·塞萬提斯（哈威爾·巴登飾）找到他，邀請他重返F1，拯救這支負債累累、排名墊底的車隊。桑尼與年輕新秀約書亞·皮爾斯（達姆森·伊德里斯飾）搭檔，兩人既是隊友又在賽道上展開激烈競爭。電影描繪桑尼如何面對過往創傷、適應現代F1賽車的挑戰，並在車隊危機中尋找救贖。故事融合高速賽車場面、車隊內部衝突與個人成長，展現F1世界的熱血與人性。

## 劇情(含爆雷完整版)
> 不想被爆雷者可以快速滑過

### 第一段：
桑尼·海耶斯（Sonny Hayes）是一位45歲左右的美國賽車手，1990年代曾是F1後起之秀，為蓮花車隊（Lotus）效力。然而，1993年西班牙大獎賽中，他與賽納（Ayrton Senna）競速時發生嚴重撞車事故，導致第四節頸椎受傷，需以骨釘固定，F1生涯就此終結。此後，他陷入人生低谷，染上賭癮，三段婚姻皆以失敗告終。電影開場，桑尼剛贏得戴通納24小時耐力賽（24 Hours of Daytona），收到前蓮花隊友、APXGP F1車隊所有者魯賓·塞萬提斯（Ruben Cervantes）的邀請，為車隊空缺席位測試。塞萬提斯透露，APXGP排名墊底且負債3億美元，若在剩餘九場比賽中無法得分，車隊將被出售。桑尼在「成為世界最佳」的激勵下，接受邀約，搭上前往英國的頭等艙。
![布萊德彼特](/images/f1_movie_pic1.jpg)

### 第二段：
在銀石賽道（Silverstone）測試中，桑尼結識車隊負責人卡斯巴·斯莫林斯基（Kaspar Smolinski）、技術總監凱特·麥克納（Kate McKenna）及新秀車手約書亞·皮爾斯（Joshua Pearce）。皮爾斯態度傲慢，擔心車隊出售會危及自己的席位，因此急於證明自己。桑尼難以適應現代F1賽車的複雜性，但憑經驗迅速發現APXGP賽車的設計缺陷。雖然他在測試中於最後彎道撞車，但因技術出色，車隊決定與他簽約。

### 第三段：
桑尼在英國大獎賽正式復出，APXGP車隊起跑表現出色，但維修站失誤導致名次下滑。桑尼無視指令，拒絕為皮爾斯讓車，二人碰撞，雙雙退賽。在匈牙利大獎賽中，桑尼利用規則，故意引發安全車，助皮爾斯獲得車隊歷史首個積分，修復二人關係。隨後，皮爾斯採納桑尼的傳統訓練法，桑尼則學習模擬器訓練，並說服凱特重新設計賽車，增強「纏鬥」能力。在義大利大獎賽的雨戰中，桑尼提議使用光頭胎（slick tires），助皮爾斯升至第二，但皮爾斯急於超車，在帕拉波里卡彎（Curva Parabolica）撞上馬克斯·維斯塔潘（Max Verstappen），賽車起火。桑尼救出皮爾斯，後者因傷缺席三場比賽，桑尼則持續得分。

### 第四段：
皮爾斯回歸後，在比利時大獎賽因激進駕駛導致與桑尼碰撞，桑尼退賽並對此震怒。賽季末，凱特組織撲克牌局，決定拉斯維加斯大獎賽的戰術優先權。皮爾斯勝出，但桑尼透露自己故意放棄必勝牌局，贏得凱特青睞，兩人共度一夜。塞萬提斯收到匿名舉報，指凱特非法升級部件，FIA要求移除部件。桑尼在拉斯維加斯因路怒與塞吉歐·培瑞茲（Sergio Pérez）碰撞，舊傷復發，塞萬提斯以安全為由解僱他。董事會成員彼得·班寧（Peter Banning）承認策劃舉報，欲罷免塞萬提斯並出售車隊，提議任命桑尼為新負責人。在阿布達比大獎賽前，皮爾斯承諾以更成熟的態度比賽，並承認義大利事故非桑尼之錯。桑尼拒絕班寧提議，說服塞萬提斯讓他參賽。FIA調查證實凱特無違規，允許APXGP使用升級部件。比賽中，皮爾斯一度領先，但被路易斯·漢米爾頓（Lewis Hamilton）和夏爾·勒克萊爾（Charles Leclerc）超越。桑尼在與喬治·羅素（George Russell）的纏鬥中碰撞，觸發紅旗，助APXGP車手換上新輪胎。重啟後，桑尼通過防守漢米爾頓，為皮爾斯創造機會，但漢米爾頓與皮爾斯碰撞，意外讓桑尼奪得職業生涯首個分站冠軍，保住車隊。賽後，桑尼與凱特確認戀情，皮爾斯拒絕梅賽德斯邀約。桑尼自F1退役，重返游牧生活，參加巴哈1000（Baja 1000）賽事。

## 心得
看《F1》電影，我選的是嘉義in89的4DX影廳(太晚去看了，只剩下午夜場11:00，看完已經一點半，雖然很好看但快累死)。票價全票530元，會員票480元，雖然蠻貴的，但是體驗非常值得。4DX的動態座椅與賽車的高速感起步、加速、轉彎和碰撞的模擬效果讓人彷彿置身車上，增強了沉浸感，甚至還有水氣味道。劇情雖然有些公式化(而且有點太浮誇，最好一直撞不會被FIA罰下場)，對於有看或是有追F1的車迷來說，建議還是直上4DX，體驗動態感，劇情就當搭配著看，身為F1老車迷(把Netflix f1影集從頭看到尾的人)來說會覺得太扯(太離譜了)，可以注意細節，像是ㄛˊ這是麥拉倫總部、這是什麼賽道這樣。對於沒看過F1，沒在追賽季的也可以這個電影當作入門，BUT不要覺得看完這部電影就很懂F1，然後看迷因之後就一直DO DO DO DO MAX verstappen(很躁，我也很愛MAX，但是隨時隨地都DO DO DO就很斜咖)，劇情的部分我就不過多評價了，就是布萊德．彼特很帥演的很好，都這把年紀還帥成這樣真是羨慕。

## 技術

### 簡介
《F1》電影利用真實F1賽道拍攝、改裝Formula 2賽車、定制攝影機系統及演員親自駕駛，結合IMAX攝影機和數位後期處理，呈現高度真實的賽車體驗。


### 真實賽道與賽車改裝
《F1》電影在2023年和2024年的F1世界錦標賽期間，於銀石（Silverstone）、蒙札（Monza）、斯帕-法蘭克爾尚（Spa-Francorchamps）、亞斯碼頭（Yas Marina）、拉斯維加斯街道賽道（Las Vegas Strip Circuit）等標誌性賽道拍攝，捕捉真實賽事氛圍。據Forbes報導，劇組與FIA合作，使用實際賽事畫面，包含墨西哥城和匈牙利環形賽道（Hungaroring），例如拉斯維加斯大獎賽僅有15分鐘拍攝窗，增加了挑戰性。劇組使用六輛改裝的Formula 2賽車，基於Dallara F2 2018底盤，配備電動馬達、Mercedes-benz AMG定制的空氣動力學車身，並延長軸距400毫米，使外觀接近現代F1賽車。賽車設置16個攝影機安裝點，減少空氣動力學干擾，提供多角度視覺效果（PetaPixel）。
![APXGP車輛](/images/f1_movie_pic2.jpg)

### 攝影技術與後期製作
電影採用定制攝影機系統，包括蘋果設計的iPhone硬體模組（A17 Pro晶片、4800萬像素，支持ProRes log格式）和索尼Rialto攝影機原型，感測器與主機分離，適應賽車狹小空間，捕捉第一人稱視角。劇組實現實時攝影機操作，通過電動雲台遠程控制平移和對焦，導演約瑟夫·科辛斯基和攝影指導克勞迪奧·米蘭達在基地站的16個螢幕上即時監控，類似《捍衛戰士：獨行俠》的技術（Formula1.com）。IMAX認證攝影機以1.90:1縱橫比拍攝，每輛賽車最多安裝15個IMAX攝影機，增強視野和畫質（Forbes）。後期製作運用數位重繪技術，將真實F1賽車塗裝替換為虛構的APXGP車隊塗裝，類似《捍衛戰士：獨行俠》的戰鬥機效果（The Ringer）。

### 演員拍攝訓練與F1車隊合作
布拉德·彼特和達姆森·伊德里斯接受數月訓練，從高性能汽車逐步升級到Formula 3和Formula 2賽車，彼特甚至駕駛2023年的麥拉倫MCL60 F1賽車，以180英里/小時的速度拍攝，減少特效和替身使用（ScreenRant）。路易斯·漢米爾頓作為製片人和技術顧問，提供劇本真實性指導，並與馬克斯·維斯塔潘、查爾斯·勒克萊爾等車手出鏡，提升電影真實感。FIA、車隊（如保時捷、麥拉倫）提供支持，保時捷在勒芒和戴通納24小時耐力賽使用APXGP塗裝的Porsche 911 GT3 R，麥拉倫技術中心作為車隊總部場景，而在電影中風洞測試的畫面，是由威廉斯(Williams)車隊所出借。

**相關報導資料：**
- [Formula1.com: How the ‘F1’ movie filmed its thrilling car sequences](https://www.formula1.com/en/latest/article/how-the-apple-original-films-f1-movie-filmed-car-sequences.2le7vDxZDbdeZdGyhfGLHZ)
- [PetaPixel: Five Insane Filming Facts About the 'F1' Movie](https://petapixel.com/2025/06/26/five-insane-filming-facts-about-the-f1-movie/)
- [Forbes: 10 Behind-The-Scenes Ways ‘F1 The Movie’ Brings Fans Closer To Racing Action](https://www.forbes.com/sites/michaelharley/2025/07/01/10-behind-the-scenes-ways-f1-the-movie-brings-fans-closer-to-racing-action/)
- [ScreenRant: How F1 The Movie Filmed Its Formula 1 Racing Scenes With Brad Pitt](https://screenrant.com/f1-the-movie-racing-scenes-filmed-how/)
- [Formula1.com: F1 Explains - How F1 The Movie was made with director Joseph Kosinski](https://www.formula1.com/en/latest/article/f1-explains-how-f1-the-movie-was-made-with-director-joseph-kosinski.2uaPicSZRTDSK1GoLMLBQ7)
]]></content>
        <author>
            <name>作者名稱</name>
        </author>
        <category label="F1"/>
        <category label="評測"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[C++ 結構（Struct）基礎與應用]]></title>
        <id>http://localhost:3000/blog/struct_c++</id>
        <link href="http://localhost:3000/blog/struct_c++"/>
        <updated>2025-07-09T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[本文介紹 C++ 結構（struct）的概念，包括定義、宣告、別名（typedef）、成員存取、初始化，以及結構與函數的應用。]]></summary>
        <content type="html"><![CDATA[
# C++ 結構（Struct）

## 本章重點
1. 認識結構（`struct`）的概念與用途。
2. 理解 `typedef` 的使用方式。
3. 分辨有無 `typedef` 的結構宣告形式。
4. 探索結構在函數中的應用。

## 簡介
結構（`struct`）是一種自定義資料型態，允許儲存不同型態的資料，與陣列或向量（僅限單一型態）不同。結構類似製造餃子的模具（定義格式），而結構體（結構變數）則是依模具製作的餃子（實例，內含不同資料）。

| **結構（模具）** | **結構體（餃子）** |
|------------------|--------------------|
| 定義資料格式，決定結構體的欄位 | 實際儲存資料的實例 |

**圖示**：結構與結構體類比（來源：<https://pic.pimg.tw/abcjcba/1622209265-791097763-g_wn.jpg>）

**與類別（class）的比較**：
- 結構和類別功能相似，但結構預設成員為公用（`public`），類別預設為私有（`private`）。
- 結構通常用於簡單資料聚合，類別則包含更多物件導向特性（如方法、繼承）。

## 宣告與建立變數

### 1. 建立結構後宣告變數
**語法**：
```cpp
struct 結構名稱 {
    資料型態1 欄位名稱1;
    資料型態2 欄位名稱2;
    // ...
}; // 注意分號

struct 結構名稱 變數名稱1, 變數名稱2, ...;
```

**範例**：
```cpp
#include <string>
struct Car {
    int price;
    std::string brand;
};

int main() {
    Car car1; // 宣告結構變數
    car1.price = 10000;
    car1.brand = "Toyota";
    return 0;
}
```

### 2. 建立結構同時宣告變數
**語法**：
```cpp
struct 結構名稱 {
    資料型態1 欄位名稱1;
    資料型態2 欄位名稱2;
    // ...
} 變數名稱1, 變數名稱2, ...;
```

**範例**：
```cpp
#include <string>
struct Car {
    int price;
    std::string brand;
} car1, car2;

int main() {
    car1.price = 10000;
    car1.brand = "Toyota";
    car2.price = 15000;
    car2.brand = "Honda";
    return 0;
}
```

### 3. 宣告結構別名（使用 `typedef`）
**語法**：
```cpp
struct 結構名稱 {
    資料型態1 欄位名稱1;
    資料型態2 欄位名稱2;
    // ...
};
typedef struct 結構名稱 新結構名稱;
```

**範例**：
```cpp
#include <string>
struct Student {
    int id;
    std::string name;
    int chinese;
    int english;
    int math;
};
typedef struct Student StudentAlias;

int main() {
    StudentAlias stu1; // 使用別名宣告變數
    stu1.id = 1;
    stu1.name = "Alice";
    return 0;
}
```

### 4. 定義結構同時取別名
**語法**：
```cpp
typedef struct {
    資料型態1 欄位名稱1;
    資料型態2 欄位名稱2;
    // ...
} 新結構名稱;
```

**範例**：
```cpp
#include <string>
typedef struct {
    int id;
    std::string name;
    int chinese;
    int english;
    int math;
} Student;

int main() {
    Student stu1; // 直接使用別名
    stu1.id = 1;
    stu1.name = "Bob";
    return 0;
}
```

## 結構成員的使用

### 1. 使用點運算子（`.`）
直接通過結構變數存取成員。

**語法**：
```cpp
結構變數名稱.欄位名稱
```

**範例**：
```cpp
#include <iostream>
#include <string>
using namespace std;

struct Car {
    int price;
    string brand;
};

int main() {
    Car car1;
    car1.price = 10000;
    car1.brand = "Toyota";
    cout << car1.brand << ": $" << car1.price << endl; // 輸出：Toyota: $10000
    return 0;
}
```

**練習**：
```cpp
#include <iostream>
#include <string>
using namespace std;

struct Data {
    string name;
    int math;
} student;

int main() {
    cin >> student.name >> student.math;
    cout << "student " << student.name << " gets " << student.math << " points" << endl;
    return 0;
}
```

**範例輸入**：
```
Alice 90
```

**範例輸出**：
```
student Alice gets 90 points
```

### 2. 使用指標運算子（`->`）
通過結構指標存取成員。

**語法**：
```cpp
結構指標->欄位名稱
```

**範例**：
```cpp
#include <iostream>
#include <string>
using namespace std;

struct Car {
    int price;
    string brand;
};

int main() {
    Car mazda;
    Car* ptr = &mazda;
    ptr->price = 100000;
    ptr->brand = "Mazda";
    cout << ptr->brand << ": $" << ptr->price << endl; // 輸出：Mazda: $100000
    return 0;
}
```

**練習：指針方式完成學生資料輸入**：
```cpp
#include <iostream>
#include <string>
using namespace std;

struct Data {
    string name;
    int math;
};

int main() {
    Data student;
    Data* ptr = &student;
    cin >> ptr->name >> ptr->math;
    cout << "student " << ptr->name << " gets " << ptr->math << " points" << endl;
    return 0;
}
```

**範例輸入**：
```
Bob 85
```

**範例輸出**：
```
student Bob gets 85 points
```

## 設定初值

### 1. 宣告結構變數並初始化
**語法**：
```cpp
struct 結構名稱 {
    // ...
};
struct 結構名稱 結構變數名稱 = {初始化內容};
```

**範例**：
```cpp
#include <string>
struct Data {
    std::string name;
    int math;
};

int main() {
    Data student = {"Nick", 90};
    return 0;
}
```

### 2. 定義結構同時初始化
**語法**：
```cpp
struct 結構名稱 {
    // ...
} 結構變數名稱 = {初始化內容};
```

**範例**：
```cpp
#include <string>
struct Data {
    std::string name;
    int math;
} student = {"Nick", 90};

int main() {
    return 0;
}
```

## 結構與函數

### 1. 傳遞整個結構
將結構變數作為參數傳入函數。

**語法**：
```cpp
struct 結構名稱 {
    // ...
} 變數1, 變數2, ...;

回傳值型態 函數名稱(struct 結構名稱 參數名稱);

回傳值型態 函數名稱(struct 結構名稱 參數名稱) {
    // ...
}
```

**練習**：
```cpp
#include <iostream>
using namespace std;

struct Scores {
    float eng;
    float math;
    float sci;
};

float avg(struct Scores my_score) {
    return (my_score.eng + my_score.math + my_score.sci) / 3;
}

int main() {
    Scores nick = {99, 90, 88};
    cout << "Average: " << avg(nick) << endl; // 輸出：92.3333
    return 0;
}
```

### 2. 傳遞結構欄位
將結構的各欄位分別傳入函數。

**語法**：
```cpp
struct 結構名稱 {
    // ...
} 變數1, 變數2, ...;

回傳值型態 函數名稱(資料型態1, 資料型態2, ...);

回傳值型態 函數名稱(資料型態1 變數1, 資料型態2 變數2, ...) {
    // ...
}
```

**練習**：
```cpp
#include <iostream>
using namespace std;

struct Scores {
    int eng;
    int math;
    int sci;
};

float avg(int score1, int score2, int score3) {
    return (float)(score1 + score2 + score3) / 3;
}

int main() {
    Scores nick = {99, 90, 88};
    cout << "Average: " << avg(nick.eng, nick.math, nick.sci) << endl; // 輸出：92.3333
    return 0;
}
```

### 3. 傳遞結構位址
通過結構指標傳遞，節省記憶體並允許修改原結構。

**練習**：
```cpp
#include <iostream>
using namespace std;

struct Scores {
    int eng;
    int math;
    int sci;
};

float avg(Scores* ptr) {
    return (float)(ptr->eng + ptr->math + ptr->sci) / 3;
}

int main() {
    Scores nick = {99, 90, 88};
    cout << "Average: " << avg(&nick) << endl; // 輸出：92.3333
    return 0;
}
```
]]></content>
        <author>
            <name>作者名稱</name>
        </author>
        <category label="C++"/>
        <category label="進階"/>
        <category label="Struct"/>
        <category label="結構"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[C++ STL 與 Vector 容器]]></title>
        <id>http://localhost:3000/blog/stl_vector_c++</id>
        <link href="http://localhost:3000/blog/stl_vector_c++"/>
        <updated>2025-07-09T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[本文介紹 C++ 標準模板庫（STL）及其核心組成，並聚焦於 vector 容器的特色、宣告、操作（插入、刪除、遍歷等）與應用。]]></summary>
        <content type="html"><![CDATA[

# C++ STL 與 Vector 容器

## STL 是什麼？
**Standard Template Library (STL)** 是 C++ 標準程式庫的一部分，提供通用的模板類別和函數，主要由以下三部分組成：
1. **容器（Containers）**：用於儲存和管理資料，如 `array`、`vector`、`map`、`queue` 等。
2. **演算法（Algorithms）**：提供常見操作，如排序、搜尋、複製等（例如 `std::sort`、`std::find`）。
3. **迭代器（Iterators）**：用於遍歷容器中的元素，作為容器與演算法的橋樑。

**圖示**：
- STL 元素結構（來源：<https://d1m75rqqgidzqn.cloudfront.net/wp-data/2021/03/23180546/23-1024x332.png>）
- STL 容器介紹（來源：<https://iq.opengenus.org/content/images/2019/05/c1.JPG>）

## Vector 容器

### 1. 特色
1. **動態調整大小**：根據需要自動擴展或縮減容量。
2. **快速插入/刪除**：在末尾操作效率高，指定位置操作需移動後續元素。
3. **連續記憶體儲存**：元素在記憶體中連續排列，支援隨機存取。
4. **全域宣告初始化**：全域宣告的 `vector` 自動將元素初始化為 0。

### 2. 標頭檔
```cpp
#include <vector>
```

### 3. 宣告
**語法**：
```cpp
std::vector<元素型態> 向量名稱;
std::vector<元素型態> 向量名稱 = {值1, 值2, ...};
std::vector<std::vector<元素型態>> 向量名稱;
```

**範例**：
```cpp
#include <vector>
#include <string>
std::vector<int> vec;
std::vector<std::string> vec2;
std::vector<int> vec3 = {1, 2, 3};
std::vector<std::vector<int>> vec4;
```

### 4. 取得元素
**語法**：
```cpp
向量名稱[索引];
向量名稱.at(索引);
```

**範例**：
```cpp
#include <vector>
std::vector<int> myVector = {1, 2, 3};
int element1 = myVector[0];
int element2 = myVector.at(1);
```

### 5. 插入元素

#### 5.1 插入到尾端
- **`push_back`**：複製或移動元素到尾端。
- **`emplace_back`**：直接在尾端構造元素，效率更高。

**範例**：
```cpp
#include <vector>
std::vector<int> myVector;
myVector.push_back(1);
myVector.emplace_back(2);
```

#### 5.2 插入到特定位置
**練習**：
```cpp
#include <vector>
#include <iostream>
using namespace std;

int main() {
    vector<int> myVector = {1, 2, 3, 4, 5};
    auto it = myVector.begin() + 2;
    myVector.insert(it, 10);
    it = myVector.begin() + 3;
    myVector.insert(it, {20, 30});
    for (int x : myVector) {
        cout << x << " ";
    }
    cout << endl;
    return 0;
}
```

**輸出**：
```
1 2 10 20 30 3 4 5
```

### 6. 刪除元素

#### 6.1 刪除尾端元素（`pop_back`）
```cpp
#include <vector>
std::vector<int> myVector = {1, 2, 3};
myVector.pop_back();
```

#### 6.2 刪除指定位置（`erase`）
**練習：刪除單一元素**：
```cpp
#include <vector>
#include <iostream>
using namespace std;

int main() {
    vector<int> demo = {1, 2, 3, 4, 5};
    auto iter = demo.erase(demo.begin() + 1);
    cout << "size is: " << demo.size() << endl;
    for (int x : demo) {
        cout << x << " ";
    }
    cout << endl << *iter << endl;
    return 0;
}
```

**輸出**：
```
size is: 4
1 3 4 5
3
```

**練習：刪除區間**：
```cpp
#include <vector>
#include <iostream>
using namespace std;

int main() {
    vector<int> demo = {1, 2, 3, 4, 5};
    auto iter = demo.erase(demo.begin() + 1, demo.end() - 1);
    cout << "size is: " << demo.size() << endl;
    cout << "capacity is: " << demo.capacity() << endl;
    for (int x : demo) {
        cout << x << " ";
    }
    cout << endl;
    return 0;
}
```

**輸出**：
```
size is: 2
capacity is: 5
1 5
```

#### 6.3 移除特定值（`remove`）
**練習**：
```cpp
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

int main() {
    vector<int> demo = {1, 3, 3, 4, 3, 5};
    auto iter = remove(demo.begin(), demo.end(), 3);
    cout << "size is: " << demo.size() << endl;
    for (auto first = demo.begin(); first < iter; ++first) {
        cout << *first << " ";
    }
    cout << endl;
    demo.erase(iter, demo.end());
    cout << "size after erase: " << demo.size() << endl;
    return 0;
}
```

**輸出**：
```
size is: 6
1 4 5
size after erase: 3
```

#### 6.4 清除所有元素（`clear`）
**練習**：
```cpp
#include <vector>
#include <iostream>
using namespace std;

int main() {
    vector<int> demo = {1, 3, 3, 4, 3, 5};
    demo.clear();
    cout << "size is: " << demo.size() << endl;
    cout << "capacity is: " << demo.capacity() << endl;
    return 0;
}
```

**輸出**：
```
size is: 0
capacity is: 6
```

### 7. 取得大小
```cpp
#include <vector>
#include <iostream>
std::vector<int> vec = {1, 2, 3};
std::cout << vec.size();
```

**輸出**：
```
3
```

### 8. 檢查是否為空
```cpp
#include <vector>
#include <iostream>
std::vector<int> vec;
std::cout << vec.empty();
```

**輸出**：
```
1
```

### 9. 迭代器
#### 9.1 For 迴圈遍歷
```cpp
#include <vector>
#include <iostream>
using namespace std;

int main() {
    vector<int> vec = {1, 2, 3, 4, 5};
    for (int i = 0; i < vec.size(); i++) {
        cout << vec[i] << " ";
    }
    cout << endl;
    return 0;
}
```

**輸出**：
```
1 2 3 4 5
```

#### 9.2 迭代器遍歷
```cpp
#include <vector>
#include <iostream>
using namespace std;

int main() {
    vector<int> vec = {1, 2, 3, 4, 5};
    for (auto it = vec.begin(); it != vec.end(); ++it) {
        cout << *it << " ";
    }
    cout << endl;
    return 0;
}
```

**輸出**：
```
1 2 3 4 5
```

#### 9.3 範圍 for 迴圈
```cpp
#include <vector>
#include <iostream>
using namespace std;

int main() {
    vector<int> vec = {1, 2, 3, 4, 5};
    for (int x : vec) {
        cout << x << " ";
    }
    cout << endl;
    return 0;
}
```

**輸出**：
```
1 2 3 4 5
```

### 10. 改變向量大小
**練習**：
```cpp
#include <vector>
#include <iostream>
using namespace std;

int main() {
    vector<int> vec1 = {2, 4, 6, 8, 10};
    vec1[4] = 1;
    cout << "vec1: ";
    for (int x : vec1) {
        cout << x << " ";
    }
    cout << endl;

    vector<int> vec2;
    vec2.resize(5);
    vec2[4] = 1;
    cout << "vec2: ";
    for (int x : vec2) {
        cout << x << " ";
    }
    cout << endl;
    return 0;
}
```

**輸出**：
```
vec1: 2 4 6 8 1
vec2: 0 0 0 0 1
```

**錯誤範例**：
```cpp
#include <vector>
#include <iostream>
using namespace std;

int main() {
    vector<int> vec1;
    vec1[4] = 1; // 錯誤：越界存取
    return 0;
}
```
]]></content>
        <author>
            <name>作者名稱</name>
        </author>
        <category label="C++"/>
        <category label="初學"/>
        <category label="STL"/>
        <category label="Vector"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[C++ 鏈結串列基礎與應用]]></title>
        <id>http://localhost:3000/blog/linked_list_c++</id>
        <link href="http://localhost:3000/blog/linked_list_c++"/>
        <updated>2025-07-09T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[本文介紹 C++ 鏈結串列的概念，包括循序串列與鏈結串列的比較、動態記憶體配置、節點操作（建立、插入、刪除），以及鏈結堆疊與佇列的實現。]]></summary>
        <content type="html"><![CDATA[
# C++ 鏈結串列（Linked List）

## 串列簡介

### 1. 循序串列（Sequential List）
- **定義**：資料儲存在連續的記憶體位置，屬於有序串列，例如陣列。
- **優點**：
  1. 搜尋方便，可隨機存取資料。
  2. 資料結構簡單，易於實現。
- **缺點**：
  1. 需預先宣告固定記憶體空間，彈性低。
  2. 插入或刪除資料需移動大量資料。
- **圖示**：循序串列記憶體結構（待補充圖示，展示連續記憶體分配）。

### 2. 鏈結串列（Linked List）
- **定義**：資料儲存在非連續記憶體，利用指標串接節點，最後節點指向 `NULL`，屬於無序串列。
- **優點**：
  1. 記憶體配置靈活，動態分配。
  2. 串列分裂與合併操作簡單。
- **缺點**：
  1. 搜尋元素耗時，需逐節點遍歷。
  2. 可靠度較低，若指標斷裂可能導致資料遺失。
- **圖示**：鏈結串列結構（待補充圖示，展示節點與指標關係）。

## 動態記憶體配置

### 1. 定義
- **動態記憶體配置**：在程式執行時向作業系統申請記憶體空間。
- **靜態記憶體配置**：在編譯時預先分配固定記憶體。
- **應用**：鏈結串列利用動態記憶體配置解決資料量未知的問題。

### 2. C 語言中的動態記憶體配置
- **配置**：
  ```cpp
  指標變數 = (資料型態*)malloc(sizeof(資料型態));
  ```
  **範例**：
  ```cpp
  int *pt = (int*)malloc(sizeof(int)); // 配置整數記憶體
  *pt = 10; // 賦值
  ```
- **釋放**：
  ```cpp
  free(指標變數);
  ```
  **範例**：
  ```cpp
  free(pt); // 釋放記憶體
  ```

### 3. C++ 中的動態記憶體配置
- **配置**：
  ```cpp
  資料型態 *指標名稱 = new 資料型態;
  ```
  **範例**：
  ```cpp
  int *pt = new int; // 配置整數記憶體
  *pt = 10; // 賦值
  ```
- **釋放**：
  ```cpp
  delete 指標名稱;
  ```
  **範例**：
  ```cpp
  delete pt; // 釋放記憶體
  pt = nullptr; // 避免野指標
  ```

### 4. 動態 vs 靜態資料結構
| **特性** | **靜態資料結構** | **動態資料結構** |
|----------|------------------|------------------|
| 記憶體使用 | 節省空間 | 需額外指標，較浪費空間 |
| 插入/刪除 | 需移動大量資料 | 只需修改指標 |
| 存取方式 | 可直接存取 | 需逐節點遍歷 |
| 搜尋方式 | 支援二分搜尋 | 不支援二分搜尋 |

## 鏈結串列基本概念

### 1. 節點結構
每個節點包含：
- `data`：儲存資料（例如整數、字元等）。
- `next`：指向下一個節點的指標，型態為節點結構的指標。

**範例**：
```cpp
struct Node {
    int data;
    Node* next; // 指向下一個節點
};
```

### 2. 首節點（Head/Front）
- **定義**：鏈結串列的起點，透過 `head` 可遍歷整個串列。
- **初始化**：
  ```cpp
  Node* head = new Node;
  head->next = nullptr; // 初始為空串列
  ```

### 3. 尾節點（Tail/Rear）
- **定義**：串列的最後節點，`next` 指向 `nullptr`，視情況可宣告 `rear` 標示。
- **初始化**：
  ```cpp
  Node* rear = new Node;
  rear->next = nullptr;
  ```
- **單節點情況**：
  ```cpp
  Node* head = new Node;
  head->next = nullptr;
  Node* rear = head; // 首尾相同
  ```

### 4. 建立新節點
```cpp
Node* node1 = new Node;
node1->data = 10;
node1->next = nullptr;
```

### 5. 加入新節點
將新節點插入串列，例如在 `nodeB` 與 `nodeC` 之間插入 `nodeE`：
```cpp
nodeB->next = nodeE;
nodeE->next = nodeC;
```

### 6. 刪除節點
刪除節點（如 `nodeC`），需將前一節點指向後一節點，並釋放記憶體：
```cpp
nodeB->next = nodeD;
delete nodeC;
```

**練習：刪除節點圖示**
- **題目**：建立含四個節點的鏈結串列（儲存字元 `A`、`B`、`C`、`D`），刪除節點 `C`。
- **解答**：
  - **初始結構**：`head -> A -> B -> C -> D -> nullptr`
  - **刪除 C**：`B->next = D; delete C;`
  - **結果結構**：`head -> A -> B -> D -> nullptr`
  - **圖示**（待補充圖示，展示節點 `C` 被移除前後的鏈結變化）。

**程式碼**：
```cpp
#include <iostream>
using namespace std;

struct Node {
    char data;
    Node* next;
};

int main() {
    // 建立串列 A -> B -> C -> D
    Node* head = new Node{'A', new Node{'B', new Node{'C', new Node{'D', nullptr}}}};
    
    // 列印原始串列
    Node* current = head;
    cout << "原始串列：";
    while (current) {
        cout << current->data << " ";
        current = current->next;
    }
    cout << endl;

    // 刪除節點 C
    Node* temp = head->next; // 指向 B
    Node* toDelete = temp->next; // 指向 C
    temp->next = toDelete->next; // B 指向 D
    delete toDelete; // 釋放 C

    // 列印結果
    current = head;
    cout << "刪除 C 後：";
    while (current) {
        cout << current->data << " ";
        current = current->next;
    }
    cout << endl;

    // 釋放串列
    while (head) {
        temp = head;
        head = head->next;
        delete temp;
    }
    return 0;
}
```

**輸出**：
```
原始串列：A B C D
刪除 C 後：A B D
```

## 鏈結串列進階處理

### 1. 建立鏈結串列
將陣列轉為鏈結串列，使用 `first`（首節點）、`current`（當前節點）、`previous`（前一節點）管理串列。

**範例**：
```cpp
#include <iostream>
using namespace std;

struct Node {
    int data;
    Node* next;
};

Node* createList(int arr[], int len) {
    Node *first = nullptr, *current = nullptr, *previous = nullptr;
    for (int i = 0; i < len; i++) {
        current = new Node;
        current->data = arr[i];
        current->next = nullptr;
        if (i == 0) {
            first = current;
        } else {
            previous->next = current;
        }
        previous = current;
    }
    return first;
}

void printList(Node* first) {
    Node* current = first;
    while (current) {
        cout << current->data << " ";
        current = current->next;
    }
    cout << endl;
}

int main() {
    int arr[] = {1, 2, 3, 4};
    Node* list = createList(arr, 4);
    printList(list); // 輸出：1 2 3 4

    // 釋放串列
    while (list) {
        Node* temp = list;
        list = list->next;
        delete temp;
    }
    return 0;
}
```

### 2. 插入節點
在符合條件的節點間插入新節點（例如按升序插入）。

**範例**：
```cpp
#include <iostream>
using namespace std;

struct Node {
    int data;
    Node* next;
};

Node* insert(Node* first, int target) {
    Node* newNode = new Node{target, nullptr};
    if (!first || first->data >= target) { // 插入到首節點或空串列
        newNode->next = first;
        return newNode;
    }

    Node *current = first->next, *previous = first;
    while (current && current->data < target) {
        previous = current;
        current = current->next;
    }
    newNode->next = current;
    previous->next = newNode;
    return first;
}

void printList(Node* first) {
    Node* current = first;
    while (current) {
        cout << current->data << " ";
        current = current->next;
    }
    cout << endl;
}

int main() {
    int arr[] = {1, 3, 5};
    Node* list = createList(arr, 3); // 使用前述 createList
    cout << "原始串列：";
    printList(list);

    list = insert(list, 4);
    cout << "插入 4 後：";
    printList(list); // 輸出：1 3 4 5

    // 釋放串列
    while (list) {
        Node* temp = list;
        list = list->next;
        delete temp;
    }
    return 0;
}
```

### 3. 刪除節點
刪除特定節點或整個串列。

**範例：刪除整個串列**：
```cpp
#include <iostream>
using namespace std;

struct Node {
    int data;
    Node* next;
};

void freeList(Node* first) {
    Node* current = first;
    while (current) {
        Node* temp = current;
        current = current->next;
        delete temp;
    }
}

int main() {
    int arr[] = {1, 2, 3};
    Node* list = createList(arr, 3);
    cout << "原始串列：";
    printList(list);

    freeList(list);
    cout << "串列已釋放" << endl;
    return 0;
}
```

### 4. 列印所有節點
**範例**（見上方 `printList` 函數）。

## 鏈結堆疊（Stack Using Linked List）

### 1. 特色
- 使用鏈結實現堆疊，無容量限制（不像陣列堆疊）。
- 後進先出（LIFO），操作在頂端（`top`）進行。
- **圖示**：鏈結堆疊 push/pop（待補充圖示，展示頂端節點變化）。

### 2. 加入新節點（Push）
將新節點加入頂端，更新 `top`。

**範例**：
```cpp
#include <iostream>
using namespace std;

struct Node {
    int data;
    Node* next;
};

void push(Node*& top, int data) {
    Node* newNode = new Node{data, top};
    top = newNode;
}

void printStack(Node* top) {
    Node* current = top;
    while (current) {
        cout << current->data << " ";
        current = current->next;
    }
    cout << endl;
}

int main() {
    Node* top = nullptr;
    push(top, 10);
    push(top, 20);
    push(top, 30);
    cout << "堆疊：";
    printStack(top); // 輸出：30 20 10

    // 釋放堆疊
    while (top) {
        Node* temp = top;
        top = top->next;
        delete temp;
    }
    return 0;
}
```

### 3. 刪除節點（Pop）
移除頂端節點，更新 `top`。

**範例**：
```cpp
#include <iostream>
using namespace std;

struct Node {
    int data;
    Node* next;
};

void pop(Node*& top) {
    if (!top) return;
    Node* temp = top;
    top = top->next;
    delete temp;
}

void printStack(Node* top) {
    Node* current = top;
    while (current) {
        cout << current->data << " ";
        current = current->next;
    }
    cout << endl;
}

int main() {
    Node* top = nullptr;
    push(top, 10);
    push(top, 20);
    cout << "原始堆疊：";
    printStack(top); // 20 10

    pop(top);
    cout << "移除頂端後：";
    printStack(top); // 10

    // 釋放堆疊
    while (top) {
        Node* temp = top;
        top = top->next;
        delete temp;
    }
    return 0;
}
```

## 鏈結佇列（Queue Using Linked List）

### 1. 特色
- 使用鏈結實現佇列，無容量限制。
- 先進先出（FIFO），加入在尾端（`rear`），移除在頭端（`front`）。
- 需維護 `front` 和 `rear` 指標。
- **圖示**：鏈結佇列 enqueue/dequeue（待補充圖示，展示頭尾節點變化）。

### 2. 加入新節點（Enqueue）
將新節點加入尾端，更新 `rear`。

**範例**：
```cpp
#include <iostream>
using namespace std;

struct Node {
    int data;
    Node* next;
};

void enqueue(Node*& front, Node*& rear, int data) {
    Node* newNode = new Node{data, nullptr};
    if (!front) {
        front = rear = newNode;
    } else {
        rear->next = newNode;
        rear = newNode;
    }
}

void printQueue(Node* front) {
    Node* current = front;
    while (current) {
        cout << current->data << " ";
        current = current->next;
    }
    cout << endl;
}

int main() {
    Node *front = nullptr, *rear = nullptr;
    enqueue(front, rear, 10);
    enqueue(front, rear, 20);
    enqueue(front, rear, 30);
    cout << "佇列：";
    printQueue(front); // 輸出：10 20 30

    // 釋放佇列
    while (front) {
        Node* temp = front;
        front = front->next;
        delete temp;
    }
    return 0;
}
```

### 3. 刪除節點（Dequeue）
移除頭端節點，更新 `front`。

**範例**：
```cpp
#include <iostream>
using namespace std;

struct Node {
    int data;
    Node* next;
};

void dequeue(Node*& front, Node*& rear) {
    if (!front) return;
    Node* temp = front;
    front = front->next;
    if (!front) rear = nullptr; // 若佇列變空，更新 rear
    delete temp;
}

void printQueue(Node* front) {
    Node* current = front;
    while (current) {
        cout << current->data << " ";
        current = current->next;
    }
    cout << endl;
}

int main() {
    Node *front = nullptr, *rear = nullptr;
    enqueue(front, rear, 10);
    enqueue(front, rear, 20);
    cout << "原始佇列：";
    printQueue(front); // 10 20

    dequeue(front, rear);
    cout << "移除頭端後：";
    printQueue(front); // 20

    // 釋放佇列
    while (front) {
        Node* temp = front;
        front = front->next;
        delete temp;
    }
    return 0;
}
```
]]></content>
        <author>
            <name>作者名稱</name>
        </author>
        <category label="C++"/>
        <category label="進階"/>
        <category label="Linked List"/>
        <category label="鏈結串列"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[C++ 類別（Class）基礎與應用]]></title>
        <id>http://localhost:3000/blog/class_c++</id>
        <link href="http://localhost:3000/blog/class_c++"/>
        <updated>2025-07-09T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[本文介紹 C++ 類別的概念，包括宣告、成員存取控制、物件、建構元、靜態成員、友誼函數及物件陣列的應用。]]></summary>
        <content type="html"><![CDATA[
# C++ 類別（Class）

## 概念
類別（`class`）是結構（`struct`）的延伸，可儲存不同資料型態的成員，並新增成員函數，支援物件導向程式設計。類別包含：
- **資料成員**：儲存物件的屬性。
- **成員函數**：定義物件的行為。

**與結構的差異**：
- 結構預設成員為公用（`public`），類別預設為私有（`private`）。
- 結構用於簡單資料聚合，類別支援複雜行為與封裝。

## 宣告
**語法**：
```cpp
class 類別名稱 {
public:
    資料型態 變數名稱;
    回傳值型態 函數名稱(型態1 引數1, 型態2 引數2) {
        return 運算式;
    }
private:
    // 私有資料成員或函數
};
```

**範例**：
```cpp
#include <iostream>
#include <string>
using namespace std;

class Car {
public:
    string color;
    string brand;
    void show_color() {
        cout << color << endl;
    }
private:
    int price;
};
```

## 特色

### 1. 成員存取控制
- **`public`**：成員可於類別內外存取。
- **`private`**：成員僅限類別內存取（預設）。
- **比較**：
  |  | 公有成員 | 私有成員 |
  |---|----------|----------|
  | 類別內存取 | ✓ | ✓ |
  | 類別外存取 | ✓ | ✗ |

**私有成員的重要性**：
1. **封裝與抽象**：隱藏內部細節，提供簡潔接口。
2. **資料隱藏與安全**：防止外部直接修改。
3. **程式重用與維護性**：降低耦合，方便修改。
4. **存取控制**：精確管理存取權限。

**範例**：
```cpp
#include <iostream>
using namespace std;

class CWin {
private:
    char id;
    int width, height;
public:
    int area() {
        return width * height;
    }
    void set_member(char c, int w, int h) {
        id = c;
        width = w;
        height = h;
    }
};

int main() {
    CWin win1;
    win1.set_member('A', 10, 10);
    cout << "Area: " << win1.area() << endl;
    return 0;
}
```

**輸出**：
```
Area: 100
```

### 2. 實例變數
每個物件的資料成員獨立，稱為**實例變數**。

### 3. 物件（Object）
- **定義**：物件是類別的實例，包含屬性與行為。
- **圖示**：類別與物件關係（來源：<https://nonlineardata.com/wp-content/uploads/2020/11/Car_Class.png>）

**宣告物件**：
```cpp
Car car1;
Car car1, car2;
```

**範例**：
```cpp
#include <iostream>
#include <string>
using namespace std;

class Car {
public:
    string color;
    string brand;
};

int main() {
    Car car1;
    car1.color = "red";
    car1.brand = "Toyota";
    cout << car1.brand << ": " << car1.color << endl;
    return 0;
}
```

**輸出**：
```
Toyota: red
```

**練習**：
```cpp
#include <iostream>
#include <string>
using namespace std;

class Car {
public:
    string color;
    string brand;
};

int main() {
    Car toyota, honda, ford;
    toyota.color = "green";
    toyota.brand = "Toyota";
    honda.color = "blue";
    honda.brand = "Honda";
    ford.color = "black";
    ford.brand = "Ford";
    cout << toyota.brand << ": " << toyota.color << endl;
    cout << honda.brand << ": " << honda.color << endl;
    cout << ford.brand << ": " << ford.color << endl;
    return 0;
}
```

**輸出**：
```
Toyota: green
Honda: blue
Ford: black
```

**注意**：
1. 不同類別的物件可同名，區分方式是存入容器（如 `vector<Car>`）。
2. 類別名稱首字母通常大寫。

## 類別成員

### 1. 資料成員
- **直接存取**：類別內可直接使用資料成員名稱。
- **使用 `this`**：指向當前物件，區分成員與參數。

**範例**：
```cpp
#include <iostream>
#include <string>
using namespace std;

class Car {
public:
    string color;
    string brand;
    void show_color() {
        cout << this->color << endl;
    }
    void set_data(string color) {
        this->color = color;
    }
};

int main() {
    Car car1;
    car1.set_data("red");
    car1.show_color();
    return 0;
}
```

**輸出**：
```
red
```

### 2. 成員函數
- **類別內定義**：
```cpp
#include <iostream>
#include <string>
using namespace std;

class Car {
public:
    string color;
    string brand;
    void show_color() {
        cout << color << endl;
    }
};

int main() {
    Car car1;
    car1.color = "blue";
    car1.show_color();
    return 0;
}
```

**輸出**：
```
blue
```

- **類別外定義**：
```cpp
#include <iostream>
#include <string>
using namespace std;

class Car {
public:
    string color;
    string brand;
    void show_color();
};

void Car::show_color() {
    cout << color << endl;
}

int main() {
    Car car1;
    car1.color = "blue";
    car1.show_color();
    return 0;
}
```

**輸出**：
```
blue
```

**練習**：
```cpp
#include <iostream>
#include <string>
using namespace std;

class Rabbit {
public:
    string name;
    int age;
    int weight;
    void show_info() {
        cout << "Rabbit " << this->name << " is " << this->age << " years old" << endl;
    }
};

int main() {
    Rabbit r1;
    r1.name = "bunny";
    r1.age = 1;
    r1.weight = 0.5;
    r1.show_info();
    return 0;
}
```

**輸出**：
```
Rabbit bunny is 1 years old
```

**函數多載**：
```cpp
#include <iostream>
using namespace std;

class MathUtils {
public:
    int add(int a, int b) {
        return a + b;
    }
    double add(double a, double b) {
        return a + b;
    }
};

int main() {
    MathUtils m;
    cout << m.add(1, 2) << endl;
    cout << m.add(3.14, 0.22) << endl;
    return 0;
}
```

**輸出**：
```
3
3.36
```

**練習：設置物件**：
```cpp
#include <iostream>
#include <string>
using namespace std;

class Rabbit {
public:
    string name;
    int age;
    int weight;
    void show_info() {
        cout << "Rabbit " << name << " is " << age << " years old" << endl;
    }
    void set_data(string name, int age, int weight) {
        this->name = name;
        this->age = age;
        this->weight = weight;
    }
};

int main() {
    Rabbit r1;
    r1.set_data("bunny", 1, 0.5);
    r1.show_info();
    return 0;
}
```

**輸出**：
```
Rabbit bunny is 1 years old
```

**練習：傳遞物件**：
```cpp
#include <iostream>
#include <string>
using namespace std;

class Rabbit {
public:
    string name;
    int age;
    int weight;
    void set_data(string name, int age, int weight) {
        this->name = name;
        this->age = age;
        this->weight = weight;
    }
};

void show_info(Rabbit r) {
    cout << "Rabbit " << r.name << " is " << r.age << " years old" << endl;
}

int main() {
    Rabbit r1;
    r1.set_data("bunny", 1, 0.5);
    show_info(r1);
    return 0;
}
```

**輸出**：
```
Rabbit bunny is 1 years old
```

## 友誼函數
- **定義**：非類別成員，可存取私有成員。
- **宣告**：
  1. 類別內以 `friend` 宣告原型，類別外定義。
  2. 類別內直接定義（可能為 `inline`）。

**範例**：
```cpp
#include <iostream>
using namespace std;

class CWin {
private:
    char id;
    int width, height;
public:
    void set_member(char c, int w, int h) {
        id = c;
        width = w;
        height = h;
    }
    friend void show_member(CWin w);
};

void show_member(CWin w) {
    cout << "window " << w.id << ": width = " << w.width << ", height = " << w.height << endl;
}

int main() {
    CWin win1;
    win1.set_member('A', 10, 10);
    show_member(win1);
    return 0;
}
```

**輸出**：
```
window A: width = 10, height = 10
```

## 靜態成員

### 1. 靜態資料成員
- **特色**：所有物件共享，屬於類別。
- **初始化**：類別外使用 `類別名稱::靜態成員名稱`。

**範例**：
```cpp
#include <iostream>
using namespace std;

class CWin {
private:
    char id;
    int width, height;
public:
    static int num;
    CWin(char i, int w, int h) : id(i), width(w), height(h) {
        num++;
    }
    CWin() {
        num++;
    }
};

int CWin::num = 0;

int main() {
    CWin win1('A', 50, 50);
    CWin win2('B', 40, 50);
    CWin win3('C', 50, 40);
    CWin my_win[4];
    cout << "Number of objects: " << CWin::num << endl;
    return 0;
}
```

**輸出**：
```
Number of objects: 7
```

**練習：靜態成員函數**：
```cpp
#include <iostream>
using namespace std;

class CWin {
private:
    char id;
    int width, height;
    static int num;
public:
    CWin(char i, int w, int h) : id(i), width(w), height(h) {
        num++;
    }
    CWin() {
        num++;
    }
    static void count() {
        cout << "已經建構的物件數量：" << num << endl;
    }
};

int CWin::num = 0;

int main() {
    CWin win1('A', 50, 50);
    CWin::count();
    CWin win2('B', 40, 50);
    CWin win3('C', 50, 40);
    CWin my_win[4];
    CWin::count();
    return 0;
}
```

**輸出**：
```
已經建構的物件數量：1
已經建構的物件數量：7
```

## 建構元

### 1. 宣告
- **類別內**：
```cpp
class Car {
    Car(string s1, string s2) {
        // 實作
    }
};
```

- **類別外**：
```cpp
class Car {
    Car(string s1, string s2);
};
Car::Car(string s1, string s2) {
    // 實作
}
```

**範例**：
```cpp
#include <iostream>
#include <string>
using namespace std;

class Car {
private:
    string color;
    string brand;
public:
    Car(string s1, string s2) : color(s1), brand(s2) {}
    void show_color() {
        cout << color << endl;
    }
};

int main() {
    Car mazda("black", "Mazda");
    mazda.show_color();
    return 0;
}
```

**輸出**：
```
black
```

### 2. 特色
1. 初始化物件。
2. 物件創建時自動執行。

### 3. 建構元多載
```cpp
#include <iostream>
#include <string>
using namespace std;

class Car {
private:
    string color;
    string brand;
    int price;
public:
    Car(string s1, string s2) : color(s1), brand(s2), price(50000) {}
    Car(string s1, string s2, int n) : color(s1), brand(s2), price(n) {}
    void show_color() {
        cout << color << endl;
    }
};

int main() {
    Car mazda("black", "Mazda");
    Car toyota("white", "Toyota", 1000000);
    mazda.show_color();
    toyota.show_color();
    return 0;
}
```

**輸出**：
```
black
white
```

### 4. 預設建構元
```cpp
#include <iostream>
#include <string>
using namespace std;

class Car {
private:
    string color;
    string brand;
    int price;
public:
    Car(string s1, string s2) : color(s1), brand(s2), price(50000) {}
    Car(string s1, string s2, int n) : color(s1), branch(s2), price(n) {}
    Car() : color("white"), brand("none"), price(90000) {}
    void show_color() {
        cout << color << endl;
    }
};

int main() {
    Car mazda("black", "Mazda");
    Car toyota("white", "Toyota", 1000000);
    Car car3;
    car3.show_color();
    return 0;
}
```

**輸出**：
```
white
```

### 5. 建構元預設值
**練習**：
```cpp
#include <iostream>
#include <string>
using namespace std;

class Car {
private:
    string color;
    string brand;
    int price;
public:
    Car(string c = "white", string b = "Toyota", int p = 300000) : color(c), brand(b), price(p) {}
    void show_color() {
        cout << color << endl;
    }
};

int main() {
    Car car1;
    Car car2("red");
    Car car3("blue", "Honda");
    car1.show_color();
    car2.show_color();
    car3.show_color();
    return 0;
}
```

**輸出**：
```
white
red
blue
```

### 6. 初始化串列
```cpp
class CWin {
private:
    char id;
    int width, height;
public:
    CWin(char i = 'D', int w = 100, int h = 100) : id(i), width(w), height(h) {}
};
```

## 其他

### 1. 傳遞物件到函數
```cpp
#include <iostream>
#include <string>
using namespace std;

class Rabbit {
public:
    string name;
    int age;
};

void show_info(Rabbit r) {
    cout << "Rabbit " << r.name << " is " << r.age << " years old" << endl;
}

int main() {
    Rabbit r1;
    r1.name = "bunny";
    r1.age = 1;
    show_info(r1);
    return 0;
}
```

**輸出**：
```
Rabbit bunny is 1 years old
```

### 2. 物件陣列
**練習**：
```cpp
#include <iostream>
using namespace std;

class CWin {
public:
    char id;
    int width, height;
    CWin(char i = 'D', int w = 100, int h = 100) : id(i), width(w), height(h) {}
    void show_area() {
        cout << width * height << endl;
    }
};

int main() {
    CWin win_arr[3];
    CWin win1('A', 50, 50);
    win1.show_area();
    win_arr[0].show_area();
    win_arr[0] = win1;
    win_arr[0].show_area();
    return 0;
}
```

**輸出**：
```
2500
10000
2500
```

**練習：傳遞物件陣列**：
```cpp
#include <iostream>
using namespace std;

class CWin {
public:
    char id;
    int width, height;
    CWin(char i = 'D', int w = 100, int h = 100) : id(i), width(w), height(h) {}
};

void print_area(CWin win_arr[], int n) {
    for (int i = 0; i < n; i++) {
        cout << "window " << win_arr[i].id << ": " << win_arr[i].width * win_arr[i].height << endl;
    }
}

int main() {
    CWin win_arr[3];
    CWin win1('A', 50, 50);
    print_area(win_arr, 3);
    return 0;
}
```

**輸出**：
```
window D: 10000
window D: 10000
window D: 10000
```
]]></content>
        <author>
            <name>作者名稱</name>
        </author>
        <category label="C++"/>
        <category label="進階"/>
        <category label="Class"/>
        <category label="類別"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[C++ 字串基礎與應用]]></title>
        <id>http://localhost:3000/blog/string_c++</id>
        <link href="http://localhost:3000/blog/string_c++"/>
        <updated>2025-07-08T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[本文介紹 C++ 字串的定義、宣告、輸入輸出方式、緩衝區處理、字串長度計算、轉數字以及分割字串的方法。]]></summary>
        <content type="html"><![CDATA[
# C++ 字串（String）

## 定義
1. **字串常數**：以雙引號（`"`）包圍的資料，例如 `"Hello"`。
2. **結束字元**：字串儲存於記憶體時，自動在結尾添加空字元 `'\0'`（ASCII 0），標記字串結束。

**圖示**：字串儲存示意（待補充圖示，展示 `"Hello"` 與 `'\0'` 的記憶體結構）。

## 宣告方式
```cpp
#include <string> // 使用 string 型態需包含
string 字串名稱 = ""; // 字串物件
char 字元陣列名稱[字串長度]; // 未初始化
char 字元陣列名稱[字串長度] = ""; // 初始化為空字串
```

**其他宣告方式**：
```cpp
char 字元陣列名稱[] = "Hello"; // 自動推斷長度（包含 '\0'）
string 字串名稱 = "Hello"; // 直接賦值
char *字元指標 = "Hello"; // 指標指向字串常數
```

## 字串的輸入與輸出

### 1. 標準資料流
C++ 使用資料流（Data Streams）處理輸入與輸出，標準資料流物件包括：
- `std::cin`：標準輸入流，從鍵盤讀取資料。
- `std::cout`：標準輸出流，輸出到控制台。
- `std::cerr`：標準錯誤流，輸出錯誤訊息。

### 2. 輸出
使用 `cout` 與資料流插入運算子 `<<` 輸出字串。

**範例**：
```cpp
#include <iostream>
#include <string>
using namespace std;

int main() {
    string s = "Hello, world!";
    cout << s << endl; // 輸出字串物件
    cout << "C++" << endl; // 輸出字串常數
    return 0;
}
```

### 3. 輸入

#### 3.1 `cin`
- 使用資料流擷取運算子 `>>` 讀取字串。
- 遇到空白、回車（Enter）或 Tab 會終止輸入。

**範例：輸入含空白的字串**：
```cpp
#include <iostream>
#include <string>
using namespace std;

int main() {
    string s;
    cout << "請輸入：";
    cin >> s;
    cout << "您輸入的是：" << s << endl;
    return 0;
}
```

**情況**：
```
請輸入：hello world
您輸入的是：hello // 僅讀取空白前的字串
```

**緩衝區影響**：
- `cin` 讀取時，將輸入存入緩衝區。
- 遇到空白或回車時停止讀取，剩餘內容留在緩衝區，可能影響後續輸入。

**範例：緩衝區問題**：
```cpp
#include <iostream>
#include <string>
using namespace std;

int main() {
    string s1, s2;
    cout << "輸入 s1：";
    cin >> s1;
    cout << s1 << endl;
    cout << "輸入 s2：";
    cin >> s2;
    cout << s2 << endl;
    return 0;
}
```

**情況**：
```
輸入 s1：hello world
hello
輸入 s2：world // 未要求輸入，直接從緩衝區讀取
```

**範例：年齡與姓名輸入**：
```cpp
#include <iostream>
#include <string>
using namespace std;

int main() {
    int age;
    string name;
    cout << "how old are you?" << endl;
    cin >> age;
    cout << "what is your name?" << endl;
    cin >> name; // 僅讀取空白前的字串
    cout << name << " is " << age << " years old." << endl;
    return 0;
}
```

**情況**：
```
how old are you?
8
what is your name?
kiki lee
kiki is 8 years old. // 未讀取 "lee"
```

#### 3.2 `cin.getline()`
- 讀取整行字串，包括空白，適用於字元陣列（`char[]`）。
- 語法：
  ```cpp
  cin.getline(字元陣列, 接收字元數, 結束字元); // 可指定結束字元
  cin.getline(字元陣列, 接收字元數); // 預設結束字元為 '\n'
  ```

**範例：字元陣列輸入**：
```cpp
#include <iostream>
using namespace std;

int main() {
    int age;
    char name[20];
    cout << "how old are you?" << endl;
    cin >> age;
    cout << "what is your name?" << endl;
    cin.getline(name, 15); // 可能因緩衝區回車失敗
    cout << name << " is " << age << " years old." << endl;
    return 0;
}
```

**情況 1**：
```
how old are you?
8
what is your name?
 is 8 years old. // 未讀取名稱，因緩衝區回車
```

**情況 2**：
```
how old are you?
8 kiki lee
what is your name?
 kiki lee is 8 years old. // 讀取空白後內容
```

**問題**：`cin` 讀取年齡後，緩衝區殘留回車，導致 `cin.getline()` 直接終止。

#### 3.3 `getline()`
- 讀取整行字串，包括空白，適用於 `string` 型態。
- 語法：
  ```cpp
  getline(cin, 字串變數);
  ```

**範例：字串型態輸入**：
```cpp
#include <iostream>
#include <string>
using namespace std;

int main() {
    int age;
    string name;
    cout << "how old are you?" << endl;
    cin >> age;
    cout << "what is your name?" << endl;
    getline(cin, name); // 可能因緩衝區回車失敗
    cout << name << " is " << age << " years old." << endl;
    return 0;
}
```

**情況 1**：
```
how old are you?
8
what is your name?
 is 8 years old. // 未讀取名稱
```

**情況 2**：
```
how old are you?
8 kiki lee
what is your name?
 kiki lee is 8 years old. // 讀取完整名稱
```

#### 3.4 解決緩衝區問題
在 `cin` 後使用 `cin.getline()` 或 `getline()` 時，需清除緩衝區的回車。

**解決方法**：
- 讀取並捨棄緩衝區內容：
  ```cpp
  cin.ignore(); // 捨棄一個字元（通常是回車）
  // 或
  cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 捨棄直到回車
  ```

**範例：字串型態（清除緩衝區）**：
```cpp
#include <iostream>
#include <string>
#include <limits>
using namespace std;

int main() {
    int age;
    string name, str;
    cout << "how old are you?" << endl;
    cin >> age;
    cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 清除緩衝區
    cout << "what is your name?" << endl;
    getline(cin, name);
    cout << name << " is " << age << " years old." << endl;
    return 0;
}
```

**情況**：
```
how old are you?
8
what is your name?
kiki lee
kiki lee is 8 years old.
```

**範例：字元陣列型態（清除緩衝區）**：
```cpp
#include <iostream>
#include <limits>
using namespace std;

int main() {
    int age;
    char name[20], str[10];
    cout << "how old are you?" << endl;
    cin >> age;
    cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 清除緩衝區
    cout << "what is your name?" << endl;
    cin.getline(name, 15);
    cout << name << " is " << age << " years old." << endl;
    return 0;
}
```

**情況**：
```
how old are you?
8
what is your name?
kiki lee
kiki lee is 8 years old.
```

#### 3.5 `cin.get()`
- 用於讀取單一字元，可接收空白。
- 語法：
  ```cpp
  int ch = cin.get(); // 返回字元 ASCII 或 EOF
  cin.get(char &ch); // 將字元存入 ch
  ```

**範例：讀取字串**：
```cpp
#include <iostream>
using namespace std;

int main() {
    char ch;
    int count = 0;
    cin.get(ch);
    while (cin.fail() == false) {
        cout << ch;
        count++;
        cin.get(ch);
    }
    cout << "\nCount: " << count << endl;
    return 0;
}
```

**範例：捨棄不需要的字元**：
```cpp
#include <iostream>
using namespace std;

int main() {
    char a[20];
    cin.get(a, 20); // 讀取最多 19 個字元（保留 '\0'）
    cout << a << endl;
    return 0;
}
```

**`cin.get(ch)` vs `ch = cin.get()`**：

| 屬性 | `cin.get(ch)` | `ch = cin.get()` |
|------|---------------|------------------|
| 傳遞方式 | 賦值給參數 `ch` | 函數返回值賦給 `ch` |
| 字元輸入返回值 | `istream` 物件（布林轉換為 `true`） | `int`（字元 ASCII 碼） |
| EOF 返回值 | `istream` 物件（布林轉換為 `false`） | `EOF` |

### 4. 練習題解答

#### 練習 1：輸入日期與天氣（回車分隔）
**要求**：輸入日期（`20230101`）與天氣（`Sunny`），用回車分隔，輸出 `It is sunny day on 20230101.`。

**解答**：
```cpp
#include <iostream>
#include <string>
#include <limits>
using namespace std;

int main() {
    string date, weather;
    cout << "輸入日期與天氣（回車分隔）：" << endl;
    cin >> date;
    cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 清除回車
    getline(cin, weather);
    cout << "It is " << weather << " day on " << date << "." << endl;
    return 0;
}
```

**輸入**：
```
20230101
Sunny
```

**輸出**：
```
It is Sunny day on 20230101.
```

#### 練習 2：輸入日期與天氣（逗號分隔）
**要求**：輸入 `20230101,Sunny`，用逗號分隔，輸出 `It is sunny day on 20230101.`。

**解答**：
```cpp
#include <iostream>
#include <string>
using namespace std;

int main() {
    char date[20], weather[20];
    cout << "輸入日期與天氣（逗號分隔）：" << endl;
    cin.getline(date, 20, ','); // 讀取逗號前內容
    cin.getline(weather, 20); // 讀取逗號後內容
    cout << "It is " << weather << " day on " << date << "." << endl;
    return 0;
}
```

**輸入**：
```
20230101,Sunny
```

**輸出**：
```
It is Sunny day on 20230101.
```

## 其他功能

### 1. 取得字串長度

#### `length()`
返回字串的字元數。
```cpp
#include <iostream>
#include <string>
using namespace std;

int main() {
    string str = "Hello, world!";
    cout << "Length: " << str.length() << endl; // 輸出 13
    return 0;
}
```

#### `size()`
與 `length()` 功能相同。
```cpp
#include <iostream>
#include <string>
using namespace std;

int main() {
    string str = "Hello, world!";
    cout << "Size: " << str.size() << endl; // 輸出 13
    return 0;
}
```

#### `sizeof()`
返回物件的記憶體大小（非字串長度）。
```cpp
#include <iostream>
#include <string>
using namespace std;

int main() {
    string str = "Hello, world!";
    cout << "sizeof(str): " << sizeof(str) << endl; // 輸出 24（取決於實作）
    return 0;
}
```

### 2. 字串運算
- **串接**：使用 `+` 或 `+=` 合併字串。
- **比較**：使用 `==`、`!=`、`<`、`>` 等比較字串。
- **存取字元**：使用 `[index]` 或 `at(index)` 存取單字元。

**範例**：
```cpp
#include <iostream>
#include <string>
using namespace std;

int main() {
    string s1 = "Hello", s2 = "World";
    string s3 = s1 + " " + s2; // 串接
    cout << s3 << endl; // Hello World
    if (s1 < s2) {
        cout << s1 << " is less than " << s2 << endl;
    }
    cout << "First char: " << s1[0] << endl; // H
    return 0;
}
```

### 3. 字串處理
- **查找**：`find()`、`rfind()` 查找子字串。
- **取代**：`replace()` 替換部分字串。
- **子字串**：`substr()` 提取子字串。
- **大小寫轉換**：需自訂或使用庫函數（如 `<algorithm>` 的 `transform`）。

**範例**：
```cpp
#include <iostream>
#include <string>
using namespace std;

int main() {
    string s = "Hello, World!";
    size_t pos = s.find("World"); // 查找子串
    if (pos != string::npos) {
        cout << "Found at: " << pos << endl; // 7
    }
    s.replace(7, 5, "C++"); // 取代 World
    cout << s << endl; // Hello, C++!
    string sub = s.substr(0, 5); // 提取子串
    cout << sub << endl; // Hello
    return 0;
}
```

### 4. 去除空白符

#### `cin`
直接忽略前後空白，簡單易用。
```cpp
#include <iostream>
#include <string>
using namespace std;

int main() {
    string str;
    while (cin >> str) {
        cout << str << endl;
    }
    return 0;
}
```

#### `istringstream`
將字串按空白分割，轉為單獨字串或數字。

**範例 1：分割字串**：
```cpp
#include <iostream>
#include <sstream>
#include <string>
using namespace std;

int main() {
    string str = "Hello C++ World";
    istringstream iss(str);
    string token;
    while (getline(iss, token, ' ')) {
        cout << token << endl;
    }
    return 0;
}
```

**範例 2：轉為數字**：
```cpp
#include <iostream>
#include <sstream>
#include <string>
using namespace std;

int main() {
    string str = "123 456 789";
    istringstream iss(str);
    int num;
    while (iss >> num) {
        cout << "整數：" << num << endl;
    }
    return 0;
}
```

#### `stringstream`
類似 `istringstream`，支援輸入與輸出。

**範例**：
```cpp
#include <iostream>
#include <sstream>
#include <string>
using namespace std;

int main() {
    string str = "Hello C++ World";
    stringstream ss(str);
    string temp;
    while (ss >> temp) {
        cout << temp << endl;
    }
    return 0;
}
```

#### `strtok`
用於字元陣列，按指定分隔符分割。

**範例**：
```cpp
#include <iostream>
#include <cstring>
using namespace std;

int main() {
    string str = "Hello C++ World";
    char *s = new char[str.size() + 1];
    strcpy(s, str.c_str());
    char *token = strtok(s, " ");
    while (token) {
        cout << token << endl;
        token = strtok(NULL, " ");
    }
    delete[] s;
    return 0;
}
```

### 5. 連續輸入
使用 `getline()` 讀取多行輸入，需設置結束條件。

**範例**：
```cpp
#include <iostream>
#include <string>
using namespace std;

int main() {
    string line;
    while (getline(cin, line)) {
        if (line.empty()) break; // 空行結束
        cout << "讀取行：" << line << endl;
    }
    return 0;
}
```

### 6. 字串轉數字
使用 `stoi()` 將字串轉為整數。

**範例**：
```cpp
#include <iostream>
#include <string>
using namespace std;

int main() {
    string str = "12345";
    int num = stoi(str);
    cout << "整數值：" << num << endl; // 12345
    return 0;
}
```

**其他轉換**：
- `stol`：轉為長整數。
- `stof`：轉為浮點數。
- `stod`：轉為雙精度浮點數。

## 延伸閱讀
- `istringstream` 詳細介紹：<https://blog.cckluo.com/post/112758074>
]]></content>
        <author>
            <name>作者名稱</name>
        </author>
        <category label="C++"/>
        <category label="初學"/>
        <category label="Strings"/>
        <category label="字串"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[C++ 堆疊與佇列]]></title>
        <id>http://localhost:3000/blog/stack_quere_c++</id>
        <link href="http://localhost:3000/blog/stack_quere_c++"/>
        <updated>2025-07-08T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[本文介紹 C++ 堆疊與佇列的基本概念，包括其特色、宣告、使用方法（push、pop、front、back 等）以及遍歷方式。]]></summary>
        <content type="html"><![CDATA[
# C++ 堆疊與佇列

堆疊（Stack）和佇列（Queue）是兩種重要的資料結構，常用於管理有序資料。它們的主要區別在於資料的存取順序。

|  | 堆疊（Stack） | 佇列（Queue） |
| -------- | -------- | -------- |
| **概念** | 後進先出（Last In, First Out, LIFO），最後加入的元素最先被移除。 | 先進先出（First In, First Out, FIFO），最先加入的元素最先被移除。 |
| **應用** | 撤銷與回復操作、函數呼叫棧、遞迴處理。 | 列印佇列、排隊系統、任務調度。 |

## 堆疊（Stack）

### 1. 特色
1. **有序串列**：由相同型態的元素組成。
2. **後進先出（LIFO）**：最後加入的元素最先被移除。
3. **單端操作**：所有操作（放入與取出）發生在頂端（Top）。
4. **動態增長**：C++ 的 `<stack>` 支援動態調整大小，無需指定固定容量。

**圖示**：堆疊 LIFO 示意圖（來源：<https://media.geeksforgeeks.org/wp-content/cdn-Uploads/20221219100314/stack.drawio2.png>）

### 2. 宣告
需包含 `<stack>` 標頭檔。

**語法**：
```cpp
#include <stack>
std::stack<元素類型> 堆疊名稱;
```

**範例**：
```cpp
#include <stack>
std::stack<int> myStack;
```

### 3. 使用

#### 3.1 取得頂端元素
```cpp
堆疊名稱.top();
```

**範例**：
```cpp
#include <iostream>
#include <stack>
using namespace std;

int main() {
    stack<int> myStack;
    myStack.push(10);
    cout << "Top: " << myStack.top() << endl; // 輸出 10
    return 0;
}
```

#### 3.2 放入（Push）
將元素加入堆疊頂端。

**語法**：
```cpp
堆疊名稱.push(元素);
```

**練習**：
```cpp
#include <iostream>
#include <stack>
using namespace std;

int main() {
    stack<int> myStack;
    myStack.push(10);
    myStack.push(20);
    myStack.push(30);
    cout << "Top: " << myStack.top() << endl; // 輸出 30
    return 0;
}
```

#### 3.3 取出（Pop）
移除頂端元素，無返回值。

**語法**：
```cpp
堆疊名稱.pop();
```

**範例**：
```cpp
#include <iostream>
#include <stack>
using namespace std;

int main() {
    stack<int> myStack;
    myStack.push(10);
    myStack.push(20);
    myStack.push(30);
    cout << "Before pop: " << myStack.top() << endl; // 30
    myStack.pop();
    cout << "After pop: " << myStack.top() << endl; // 20
    return 0;
}
```

#### 3.4 判斷是否為空
```cpp
堆疊名稱.empty();
```
- 返回 `true` 表示堆疊為空，`false` 表示非空。

#### 3.5 判斷是否為滿
- C++ 的 `<stack>` 為動態結構，無固定容量限制，因此無 `isFull()` 函數。
- **修正**：原文件中 `isFull()` 不適用於標準 `<stack>`，可忽略或用於自定義固定大小堆疊。

**範例：檢查空狀態**：
```cpp
#include <iostream>
#include <stack>
using namespace std;

int main() {
    stack<int> myStack;
    cout << "Is empty? " << (myStack.empty() ? "Yes" : "No") << endl; // Yes
    myStack.push(10);
    cout << "Is empty? " << (myStack.empty() ? "Yes" : "No") << endl; // No
    return 0;
}
```

#### 3.6 遍歷
- 堆疊無迭代器，需通過 `top()` 和 `pop()` 遍歷。
- **注意**：遍歷會移除元素，需謹慎操作。

**範例：遍歷堆疊**：
```cpp
#include <iostream>
#include <stack>
using namespace std;

int main() {
    stack<int> myStack;
    myStack.push(10);
    myStack.push(20);
    myStack.push(30);
    while (!myStack.empty()) {
        cout << myStack.top() << " ";
        myStack.pop();
    } // 輸出 30 20 10
    cout << endl;
    return 0;
}
```

## 佇列（Queue）

### 1. 特色
1. **先進先出（FIFO）**：最先加入的元素最先移除。
2. **雙端操作**：加入（enqueue）在尾端，移除（dequeue）在頭端。
3. **動態增長**：C++ 的 `<queue>` 支援動態調整大小。

**圖示**：佇列 FIFO 示意圖（來源：<https://media.geeksforgeeks.org/wp-content/cdn-Uploads/20221213113312/Queue-Data-Structures.png>）

**操作示意**：佇列的 push 和 pop（來源：<https://www.codingeek.com/wp-content/uploads/2016/09/push-popQ.png>）

### 2. 宣告
需包含 `<queue>` 標頭檔。

**語法**：
```cpp
#include <queue>
std::queue<元素類型> 佇列名稱;
```

**範例**：
```cpp
#include <queue>
std::queue<int> myQueue;
```

### 3. 使用

#### 3.1 取得第一個元素
```cpp
佇列名稱.front();
```

**範例**：
```cpp
#include <iostream>
#include <queue>
using namespace std;

int main() {
    queue<int> myQueue;
    myQueue.push(10);
    cout << "Front: " << myQueue.front() << endl; // 輸出 10
    return 0;
}
```

#### 3.2 取得最後一個元素
```cpp
佇列名稱.back();
```

**範例**：
```cpp
#include <iostream>
#include <queue>
using namespace std;

int main() {
    queue<int> myQueue;
    myQueue.push(10);
    myQueue.push(20);
    cout << "Back: " << myQueue.back() << endl; // 輸出 20
    return 0;
}
```

#### 3.3 放入（Enqueue）
將元素加入佇列尾端。

**語法**：
```cpp
佇列名稱.push(元素);
```

**練習**：
```cpp
#include <iostream>
#include <queue>
using namespace std;

int main() {
    queue<int> myQueue;
    myQueue.push(10);
    myQueue.push(20);
    myQueue.push(30);
    cout << "Front: " << myQueue.front() << endl; // 10
    cout << "Back: " << myQueue.back() << endl; // 30
    return 0;
}
```

#### 3.4 取出（Dequeue）
移除頭端元素，無返回值。

**語法**：
```cpp
佇列名稱.pop();
```

**範例**：
```cpp
#include <iostream>
#include <queue>
using namespace std;

int main() {
    queue<int> myQueue;
    myQueue.push(10);
    myQueue.push(20);
    myQueue.push(30);
    cout << "Before pop - Front: " << myQueue.front() << ", Back: " << myQueue.back() << endl; // 10, 30
    myQueue.pop();
    cout << "After pop - Front: " << myQueue.front() << ", Back: " << myQueue.back() << endl; // 20, 30
    return 0;
}
```

#### 3.5 判斷是否為空
```cpp
佇列名稱.empty();
```
- 返回 `true` 表示佇列為空，`false` 表示非空。

**範例**：
```cpp
#include <iostream>
#include <queue>
using namespace std;

int main() {
    queue<int> myQueue;
    cout << "Is empty? " << (myQueue.empty() ? "Yes" : "No") << endl; // Yes
    myQueue.push(10);
    cout << "Is empty? " << (myQueue.empty() ? "Yes" : "No") << endl; // No
    return 0;
}
```

#### 3.6 遍歷
- 佇列無迭代器，需通過 `front()` 和 `pop()` 遍歷。
- **注意**：遍歷會移除元素，需謹慎操作。

**範例：遍歷佇列**：
```cpp
#include <iostream>
#include <queue>
using namespace std;

int main() {
    queue<int> myQueue;
    myQueue.push(10);
    myQueue.push(20);
    myQueue.push(30);
    while (!myQueue.empty()) {
        cout << myQueue.front() << " ";
        myQueue.pop();
    } // 輸出 10 20 30
    cout << endl;
    return 0;
}
```
]]></content>
        <author>
            <name>作者名稱</name>
        </author>
        <category label="C++"/>
        <category label="初學"/>
        <category label="Stack"/>
        <category label="Queue"/>
        <category label="堆疊"/>
        <category label="佇列"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[C++ 排序方法介紹]]></title>
        <id>http://localhost:3000/blog/sorting_c++</id>
        <link href="http://localhost:3000/blog/sorting_c++"/>
        <updated>2025-07-08T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[本文介紹 C++ 中常用的排序方法，包括氣泡排序、選擇排序、插入排序、快速排序和合併排序。]]></summary>
        <content type="html"><![CDATA[# C++ 排序（Sorting）

## 本章重點
1. 認識多種排序方法及其應用場景。
2. 理解穩定與不穩定排序的差異。
3. 比較內部排序與外部排序的適用情境。

## 簡介
排序是將資料按特定順序（例如由小到大或由大到小）排列的過程，有助於提高資料搜尋和處理效率。不同的排序方法在時間複雜度、穩定性及適用場景上各有優劣。

## 排序方法一覽表

| 排序方式 | 氣泡排序 | 選擇排序 | 插入排序 | 快速排序 | 合併排序 |
|----------|----------|----------|----------|----------|----------|
| **最壞時間** | $O(n^2)$ | $O(n^2)$ | $O(n^2)$ | $O(n^2)$ | $O(n \log n)$ |
| **平均時間** | $O(n^2)$ | $O(n^2)$ | $O(n^2)$ | $O(n \log n)$ | $O(n \log n)$ |
| **穩定度** | 穩定 | 不穩定 | 穩定 | 不穩定 | 穩定 |
| **備註** | 適合小規模資料 | 適合小規模資料 | 適合部分已排序資料 | 適合大規模資料 | 適用於外部排序 |

### 穩定與不穩定排序
- **穩定排序**：鍵值相同的元素在排序後保持相對順序不變。
  - 範例：
    - 排序前：`3, 5, 19, 1, 3+, 10`（兩個 `3`，第二個標為 `3+`）
    - 排序後：`1, 3, 3+, 5, 10, 19`（兩個 `3` 順序不變）
- **不穩定排序**：鍵值相同的元素在排序後相對順序可能改變。
  - 範例：
    - 排序前：`3, 5, 19, 1, 3+, 10`
    - 排序後：`1, 3+, 3, 5, 10, 19`（兩個 `3` 順序改變）

### 內部與外部排序
- **內部排序（Internal Sort）**：
  - 定義：所有資料在主記憶體（RAM）內完成排序。
  - 適用：小規模資料。
- **外部排序（External Sort）**：
  - 定義：資料量過大，需借助輔助記憶體（如硬碟）完成排序。
  - 適用：大規模資料。

---

## 1. 氣泡排序（Bubble Sort）

### 定義
氣泡排序通過逐次比較相鄰元素，若順序錯誤則交換，逐步將較大（或較小）元素「浮」到正確位置，類似氣泡上升。

### 特色
1. 回合數：資料個數減 1（$n-1$）。
2. 每回合至少將一個元素排到正確位置。
3. 穩定排序。
4. 適合小規模資料。

### 原理
- 比較相鄰元素，按排序條件交換。
- 每回合將最大（或最小）元素移到末端。
- **圖示**：氣泡排序過程（待補充圖示，展示元素交換）。

### 練習
```cpp
#include <iostream>
using namespace std;

void bubbleSort(int arr[], int size) {
    for (int i = size - 1; i >= 1; i--) {
        for (int j = 0; j < i; j++) {
            if (arr[j] > arr[j + 1]) {
                swap(arr[j], arr[j + 1]);
            }
        }
    }
}

int main() {
    int arr[7] = {64, 34, 25, 12, 22, 11, 90};
    cout << "排序前：";
    for (int num : arr) {
        cout << num << " ";
    }
    cout << endl;

    bubbleSort(arr, 7);

    cout << "排序後：";
    for (int num : arr) {
        cout << num << " ";
    }
    cout << endl; // 輸出：11 12 22 25 34 64 90
    return 0;
}
```

---

## 2. 選擇排序（Selection Sort）

### 定義
選擇排序從資料中選出最小（或最大）元素，與當前位置交換，逐回合確定一個元素的正確位置。

### 特色
1. 回合數：資料個數減 1（$n-1$）。
2. 每回合確定一個元素的位置。
3. 不穩定排序。
4. 適合小規模資料。

### 原理
- 每回合從未排序部分選出最小元素，與回合起始位置交換。
- **圖示**：選擇排序過程（待補充圖示，展示最小元素選擇與交換）。

### 練習
```cpp
#include <iostream>
using namespace std;

void selectionSort(int arr[], int size) {
    for (int i = 0; i < size - 1; i++) {
        int minIndex = i;
        for (int j = i + 1; j < size; j++) {
            if (arr[j] < arr[minIndex]) {
                minIndex = j;
            }
        }
        swap(arr[i], arr[minIndex]);
    }
}

int main() {
    int arr[7] = {64, 34, 25, 12, 22, 11, 90};
    cout << "排序前：";
    for (int num : arr) {
        cout << num << " ";
    }
    cout << endl;

    selectionSort(arr, 7);

    cout << "排序後：";
    for (int num : arr) {
        cout << num << " ";
    }
    cout << endl; // 輸出：11 12 22 25 34 64 90
    return 0;
}
```

---

## 3. 插入排序（Insertion Sort）

### 定義
插入排序將未排序元素逐一插入已排序部分的適當位置，類似整理撲克牌。

### 特色
1. 回合數：資料個數減 1（$n-1$）。
2. 每回合將一個元素插入正確位置。
3. 穩定排序。
4. 適合部分已排序的資料。

### 原理
- 將未排序元素與已排序部分比較，插入適當位置。
- **圖示**：插入排序過程（來源：<https://www.geeksforgeeks.org/insertion-sort/>）。

### 練習
```cpp
#include <iostream>
using namespace std;

void insertionSort(int arr[], int size) {
    for (int i = 1; i < size; i++) {
        int key = arr[i];
        int j = i - 1;
        while (j >= 0 && arr[j] > key) {
            arr[j + 1] = arr[j];
            j--;
        }
        arr[j + 1] = key;
    }
}

int main() {
    int arr[5] = {12, 11, 13, 5, 6};
    cout << "排序前：";
    for (int num : arr) {
        cout << num << " ";
    }
    cout << endl;

    insertionSort(arr, 5);

    cout << "排序後：";
    for (int num : arr) {
        cout << num << " ";
    }
    cout << endl; // 輸出：5 6 11 12 13
    return 0;
}
```

---

## 4. 快速排序（Quick Sort）

### 定義
快速排序通過選取一個基準值（pivot），將資料分為小於和大于基準值的兩部分，遞迴排序子集合。

### 特色
1. 回合數：最多資料個數減 1（$n-1$）。
2. 需要額外堆疊空間（遞迴）。
3. 不穩定排序。
4. 平均效率高，適合大規模資料。

### 原理
1. 選取基準值（pivot，通常取最後元素）。
2. 分割：將小於 pivot 的元素放左邊，大於 pivot 的放右邊。
3. 遞迴：對左右子集合重複步驟 1 和 2。
- **圖示**：快速排序過程（來源：<https://www.geeksforgeeks.org/quick-sort/>）。

**範例**（原始資料：`26, 5, 37, 1, 61, 11, 59, 15, 48, 19`）：
1. 選 `pivot = 19`，從左找大於 19 的 `Ki`，從右找小於 19 的 `Kj`，交換。
2. 重複直到 `i >= j`，將 `pivot` 與 `Kj` 交換。
3. 以分割點遞迴處理左右子集合。

### 練習
```cpp
#include <iostream>
using namespace std;

int partition(int arr[], int low, int high) {
    int pivot = arr[high];
    int i = low - 1;
    for (int j = low; j < high; j++) {
        if (arr[j] < pivot) {
            i++;
            swap(arr[i], arr[j]);
        }
    }
    swap(arr[i + 1], arr[high]);
    return i + 1;
}

void quickSort(int arr[], int low, int high) {
    if (low < high) {
        int pi = partition(arr, low, high);
        quickSort(arr, low, pi - 1);
        quickSort(arr, pi + 1, high);
    }
}

int main() {
    int arr[6] = {10, 7, 8, 9, 1, 5};
    cout << "排序前：";
    for (int num : arr) {
        cout << num << " ";
    }
    cout << endl;

    quickSort(arr, 0, 5);

    cout << "排序後：";
    for (int num : arr) {
        cout << num << " ";
    }
    cout << endl; // 輸出：1 5 7 8 9 10
    return 0;
}
```

---

## 5. 合併排序（Merge Sort）

### 定義
合併排序採用「分而治之」策略，將陣列分割至最小單位（長度為 1），再逐對合併並排序。

### 特色
1. 回合數：取決於分割層次，約 $\log n$ 層。
2. 需要額外記憶體空間（用於合併）。
3. 穩定排序。
4. 適合內部與外部排序，特別是大規模資料。

### 原理
1. 分割：將陣列分為長度為 1 的子陣列。
2. 合併：將子陣列成對合併，保持排序順序。
3. 重複合併直到形成完整排序陣列。
- **圖示**：合併排序過程（待補充圖示，展示分割與合併）。

**範例：偶數個資料**（`25, 57, 48, 37, 12, 92, 86, 33`）：
- 準備：`[25, 57][48, 37][12, 92][86, 33]`
- 第一回合：`[25, 57][37, 48][12, 92][33, 86]`
- 第二回合：`[25, 37, 48, 57][12, 33, 86, 92]`
- 第三回合：`[12, 25, 33, 37, 48, 57, 86, 92]`

**範例：奇數個資料**（`37, 57, 32, 23, 15`）：
- 準備：`[37, 57][32, 23][15]`
- 第一回合：`[37, 57][23, 32][15]`
- 第二回合：`[23, 32, 37, 57][15]`
- 第三回合：`[15, 23, 32, 37, 57]`

### 練習
```cpp
#include <iostream>
using namespace std;

void merge(int arr[], int left, int mid, int right) {
    int n1 = mid - left + 1;
    int n2 = right - mid;
    int leftArr[n1], rightArr[n2];

    for (int i = 0; i < n1; i++) leftArr[i] = arr[left + i];
    for (int i = 0; i < n2; i++) rightArr[i] = arr[mid + 1 + i];

    int i = 0, j = 0, k = left;
    while (i < n1 && j < n2) {
        if (leftArr[i] <= rightArr[j]) {
            arr[k++] = leftArr[i++];
        } else {
            arr[k++] = rightArr[j++];
        }
    }
    while (i < n1) arr[k++] = leftArr[i++];
    while (j < n2) arr[k++] = rightArr[j++];
}

void mergeSort(int arr[], int left, int right) {
    if (left < right) {
        int mid = left + (right - left) / 2;
        mergeSort(arr, left, mid);
        mergeSort(arr, mid + 1, right);
        merge(arr, left, mid, right);
    }
}

int main() {
    int arr[6] = {12, 11, 13, 5, 6, 7};
    cout << "排序前：";
    for (int num : arr) {
        cout << num << " ";
    }
    cout << endl;

    mergeSort(arr, 0, 5);

    cout << "排序後：";
    for (int num : arr) {
        cout << num << " ";
    }
    cout << endl; // 輸出：5 6 7 11 12 13
    return 0;
}
```
]]></content>
        <author>
            <name>作者名稱</name>
        </author>
        <category label="C++"/>
        <category label="初學"/>
        <category label="Sorting"/>
        <category label="排序"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[C++ 指標與參照]]></title>
        <id>http://localhost:3000/blog/pointer_c++</id>
        <link href="http://localhost:3000/blog/pointer_c++"/>
        <updated>2025-07-08T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[本文介紹 C++ 指標與參照的概念，包括指標的宣告與運算、函數指標、陣列與雙重指標、靜態與動態記憶體配置。]]></summary>
        <content type="html"><![CDATA[
# C++ 指標與參照

## 指標（Pointer）

### 1. 宣告指標變數
指標用於儲存變數的記憶體位址。

**語法**：
```cpp
資料型態 *指標變數;
```

**範例**：
```cpp
int *ptr; // 宣告整數指標
```

**指向變數**：
```cpp
int num = 20;
int *ptr = &num; // ptr 指向 num 的位址
// 或
int *ptr;
ptr = &num;
```

### 2. 介紹
1. **指標儲存位址**：指標儲存變數的記憶體位址，`ptr` 指向變數 `a` 表示 `ptr` 儲存 `a` 的位址。
2. **指標自身有位址**：指標變數本身也有記憶體位址，與其指向的變數位址無關。
3. **重新指向**：指標可指向另一同型態變數。
4. **固定大小**：指標本身佔 4 byte（32 位系統）或 8 byte（64 位系統），與指向的資料型態無關。

**範例：指標大小**：
```cpp
#include <iostream>
using namespace std;

int main() {
    int *iptr;
    char *cptr;
    cout << "sizeof(iptr)=" << sizeof(iptr) << endl; // 指標大小
    cout << "sizeof(cptr)=" << sizeof(cptr) << endl; // 指標大小
    cout << "sizeof(*iptr)=" << sizeof(*iptr) << endl; // 整數大小
    cout << "sizeof(*cptr)=" << sizeof(*cptr) << endl; // 字元大小
    return 0;
}
```

**圖示**：
- 指標指向變數的記憶體位址（待補充圖示）。
- 指標自身的記憶體位址（待補充圖示）。

### 3. 運算子
1. **位址運算子 `&`**：取得變數的記憶體位址。
2. **取值運算子 `*`**：取得指標指向變數的內容。

**範例**：
```cpp
int num = 20;
int *ptr = &num; // &num 取得 num 位址
cout << *ptr;    // *ptr 取得 num 的值（20）
```

### 4. 指標與函數的應用

#### 4.1 傳遞指標到函數
**語法**：
```cpp
傳回值型態 函數名稱(資料型態 *指標變數) {
    // 函數內容
}
```

**呼叫方式**：
```cpp
int a = 10;
int *ptr = &a;
func(&a); // 傳遞 a 的位址
func(ptr); // 傳遞指標
```

#### 4.2 回傳指標
**語法**：
```cpp
傳回值型態 *函數名稱(資料型態 引數) {
    // 函數內容
    return 指標;
}
```

**練習：回傳兩數最大值的指標**：
```cpp
#include <iostream>
using namespace std;

int *max(int *p1, int *p2) {
    if (*p1 > *p2) {
        return p1;
    } else {
        return p2;
    }
}

int main() {
    int a = 12, b = 19, *ptr;
    ptr = max(&a, &b);
    cout << "max=" << *ptr << endl; // 輸出 19
    return 0;
}
```

#### 4.3 傳值與傳址的差異
- **傳值（Pass by Value）**：傳遞變數副本，函數內修改不影響原變數。
- **傳址（Pass by Address）**：傳遞變數位址，函數內修改影響原變數。

**傳值範例**（無效交換）：
```cpp
#include <iostream>
using namespace std;

void swap(int x, int y) {
    int tmp = x;
    x = y;
    y = tmp;
}

int main() {
    int a = 5, b = 20;
    cout << "交換之前 a=" << a << ", b=" << b << endl;
    swap(a, b);
    cout << "交換之後 a=" << a << ", b=" << b << endl; // a=5, b=20
    return 0;
}
```

**傳址範例**（有效交換）：
```cpp
#include <iostream>
using namespace std;

void swap(int *p1, int *p2) {
    int tmp = *p1;
    *p1 = *p2;
    *p2 = tmp;
}

int main() {
    int a = 5, b = 20;
    cout << "交換之前 a=" << a << ", b=" << b << endl;
    swap(&a, &b);
    cout << "交換之後 a=" << a << ", b=" << b << endl; // a=20, b=5
    return 0;
}
```

**狀況說明**（原文件中的 `!` 標記）：
- 傳值：函數內操作副本，原變數不變。
- 傳址：函數內操作原變數位址，修改生效。
- 注意：傳址需小心，避免意外修改或空指標（null pointer）問題。
- 指標操作需確保指向有效記憶體。

### 5. 函數指標（Function Pointer）
函數名稱儲存函數的起始位址，可用函數指標指向並呼叫。

**語法**：
```cpp
傳回值型態 (*指標變數名稱)(引數型態1, 引數型態2, ...);
```

**範例**：
```cpp
#include <iostream>
using namespace std;

int square(int n) {
    return n * n;
}

int main() {
    int (*pf)(int);
    pf = square;
    cout << "square(5)=" << (*pf)(5) << endl; // 輸出 25
    return 0;
}
```

**傳遞函數指標**：
```cpp
#include <iostream>
using namespace std;

double triangle(double base, double height) {
    return base * height / 2;
}

void show_area(double x, double y, double (*pf)(double, double)) {
    cout << "Area=" << (*pf)(x, y) << endl;
}

int main() {
    show_area(4, 6.6, triangle); // 輸出 Area=13.2
    return 0;
}
```

### 6. 指標與陣列的關係

#### 6.1 指標的算術運算
- 指標可進行加減運算，移動單位為指向資料型態的大小（byte）。
- 陣列名稱是指標常數，指向陣列首元素。

**範例：存取陣列**：
```cpp
#include <iostream>
using namespace std;

int main() {
    int a[3] = {5, 7, 9};
    cout << "a[0]=" << a[0] << ", *(a+0)=" << *(a+0) << endl;
    cout << "a[1]=" << a[1] << ", *(a+1)=" << *(a+1) << endl;
    cout << "a[2]=" << a[2] << ", *(a+2)=" << *(a+2) << endl;
    return 0;
}
```

**練習：計算陣列總和**：
- **方法一**（使用陣列名稱）：
  ```cpp
  #include <iostream>
  using namespace std;

  int main() {
      int a[5] = {1, 2, 3, 4, 5}, sum = 0;
      for (int i = 0; i < 5; i++) {
          sum += *(a + i);
      }
      cout << "Sum=" << sum << endl; // 輸出 15
      return 0;
  }
  ```

- **方法二**（使用指標）：
  ```cpp
  #include <iostream>
  using namespace std;

  int main() {
      int a[5] = {1, 2, 3, 4, 5}, sum = 0;
      int *ptr = a;
      for (int i = 0; i < 5; i++) {
          sum += *(ptr++);
      }
      cout << "Sum=" << sum << endl; // 輸出 15
      return 0;
  }
  ```

**注意**：
- 陣列名稱（如 `a`）是**指標常數**，不可修改（`a = a + 1` 無效）。
- 指標變數（如 `ptr`）可修改（`ptr = ptr + 1` 有效）。

**練習：指標常數的位址與值**：
```cpp
#include <iostream>
using namespace std;

int main() {
    int a[5] = {32, 16, 35, 65, 52};
    cout << "a=" << a << endl; // 陣列首地址
    cout << "&a=" << &a << endl; // 陣列本身的地址
    for (int i = 0; i < 5; i++) {
        cout << "&a[" << i << "]=" << &a[i] << endl; // 各元素地址
    }
    return 0;
}
```

**傳遞陣列到函數**：
```cpp
#include <iostream>
using namespace std;

void func(int *arr, int n) {
    for (int i = 0; i < n; i++) {
        cout << arr[i] << ' ';
    }
    cout << endl;
}

int main() {
    int arr[3] = {1, 2, 3};
    func(arr, 3); // 傳遞陣列首地址
    return 0;
}
```

#### 6.2 指標陣列
儲存指標的陣列，常用於字串陣列。

**語法**：
```cpp
資料型態 *陣列名稱[元素個數];
```

**範例**：
```cpp
#include <iostream>
using namespace std;

int main() {
    int x = 1, y = 2, z = 3;
    int *ptr[3] = {&x, &y, &z};
    for (int i = 0; i < 3; i++) {
        cout << *ptr[i] << ' ';
    }
    cout << endl;
    return 0;
}
```

#### 6.3 指標指向字串
字串可用字元陣列或字元指標表示。

**範例**：
```cpp
#include <iostream>
using namespace std;

int main() {
    char name[20];
    char *ptr = "how are you?";
    cout << "what's your name?" << endl;
    cin.getline(name, 20);
    cout << "hi, " << name << ", " << ptr << endl;
    return 0;
}
```

**字串陣列範例**：
```cpp
#include <iostream>
using namespace std;

int main() {
    char *ptr[3] = {"apple", "banana", "cherry"};
    for (int i = 0; i < 3; i++) {
        cout << ptr[i] << endl;
    }
    return 0;
}
```

#### 6.4 雙重指標（Pointer to Pointer）
指向指標的指標，儲存另一指標的位址。

**語法**：
```cpp
資料型態 **雙重指標;
資料型態 *(*雙重指標); // 可加括號
```

**二維陣列與雙重指標**：
- 二維陣列名稱可視為指向一維陣列的指標。
- `*(num + m) + n`：第 m+1 列，第 n+1 行的位址。
- `*(*(num + m) + n)`：第 m+1 列，第 n+1 行的值。

**練習：印出二維陣列位址與值**：
{% raw %}
```cpp
#include <iostream>
using namespace std;

int main() {
    int num[3][4] = {{12, 23, 42, 18}, {43, 22, 16, 14}, {31, 13, 19, 28}};
    for (int m = 0; m < 3; m++) {
        for (int n = 0; n < 4; n++) {
            cout << "num[" << m << "][" << n << "]=" << *(*(num + m) + n);
            cout << ", 地址=" << *(num + m) + n << endl;
        }
    }
    return 0;
}
```
{% endraw %}

**圖示**：
- 二維陣列與指標陣列的關係（待補充圖示）。
- 雙重指標存取二維陣列的示意（待補充圖示）。

### 7. 靜態與動態記憶體配置

#### 7.1 靜態記憶體配置
- **定義**：編譯時分配固定記憶體，程式執行時使用。
- **特點**：記憶體大小固定，生命週期隨程式執行。

**圖示**：靜態記憶體配置示意（待補充圖示）。

#### 7.2 動態記憶體配置
- **定義**：執行時從堆（heap）分配記憶體。
- **特點**：靈活分配，需手動釋放。

**指標創建與釋放**：
```cpp
型態A *指標變數名稱;
指標變數名稱 = new 型態A;
delete 指標變數名稱; // 釋放記憶體
```

**範例：動態配置整數**：
```cpp
#include <iostream>
using namespace std;

int main() {
    int *a = new int; // 分配整數記憶體
    *a = 5;
    cout << "*a=" << *a << endl; // 輸出 5
    delete a; // 釋放記憶體
    a = nullptr; // 避免野指標
    // cout << "*a=" << *a << endl; // 錯誤：訪問已釋放記憶體
    return 0;
}
```

**陣列創建與釋放**：
```cpp
型態A *指標變數 = new 型態A[個數];
delete[] 指標變數; // 釋放陣列記憶體
指標變數 = nullptr;
```

**練習：動態配置整數陣列**：
```cpp
#include <iostream>
using namespace std;

int main() {
    int *a = new int[5];
    for (int i = 0; i < 5; i++) {
        a[i] = i * 2;
        cout << "a[" << i << "]=" << a[i] << " ";
    }
    cout << endl;
    delete[] a;
    a = nullptr;
    return 0;
}
```

**範例：動態配置字串**：
```cpp
#include <iostream>
#include <cstring>
using namespace std;

char *setString(const char *text) {
    char *ptr = new char[strlen(text) + 1];
    strcpy(ptr, text);
    return ptr;
}

int main() {
    char *str = setString("hello c++");
    cout << str << endl;
    delete[] str;
    str = nullptr;
    return 0;
}
```

### 8. 指標與參照

#### 8.1 指標
使用 `&`（位址運算子）和 `*`（取值運算子）操作變數位址與內容。

#### 8.2 參照
參照是變數的別名，直接操作原變數。

**語法**：
```cpp
資料型態 &參照名稱 = 變數名稱;
```

**範例**：
```cpp
#include <iostream>
using namespace std;

int main() {
    int x = 5;
    int &ref = x; // ref 是 x 的別名
    cout << "x=" << x << ", ref=" << ref << endl; // x=5, ref=5
    ref = 10; // 修改 ref，等同修改 x
    cout << "x=" << x << ", ref=" << ref << endl; // x=10, ref=10
    return 0;
}
```

**練習：指標與參照結合**：
```cpp
#include <iostream>
using namespace std;

int main() {
    int a = 10, &ref = a;
    int b = 15, *ptr = &b;
    cout << a << "+" << b << "=" << ref + *ptr << endl; // 輸出 25
    return 0;
}
```

#### 8.3 引數傳遞方式
1. **傳值（Pass by Value）**：傳遞副本，函數內修改不影響原變數。
2. **傳址（Pass by Address）**：傳遞位址，函數內修改影響原變數。
3. **傳參照（Pass by Reference）**：傳遞別名，函數內修改影響原變數。

**傳參照範例**：
```cpp
#include <iostream>
using namespace std;

void swap(int &x, int &y) {
    int tmp = x;
    x = y;
    y = tmp;
}

int main() {
    int a = 5, b = 20;
    cout << "交換之前 a=" << a << ", b=" << b << endl;
    swap(a, b);
    cout << "交換之後 a=" << a << ", b=" << b << endl; // a=20, b=5
    return 0;
}
```

**圖示**：傳值、傳址、傳參照的比較（待補充圖示）。
]]></content>
        <author>
            <name>作者名稱</name>
        </author>
        <category label="C++"/>
        <category label="初學"/>
        <category label="Pointers"/>
        <category label="指標"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[C++ 函數與變數等級]]></title>
        <id>http://localhost:3000/blog/function_variables_c++</id>
        <link href="http://localhost:3000/blog/function_variables_c++"/>
        <updated>2025-07-08T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[本文介紹 C++ 函數的優點、宣告方式、回傳值、呼叫方法、inline 函數、變數等級以及遞迴概念，包含程式碼範例與遞迴階乘實作，適合初學者學習。]]></summary>
        <content type="html"><![CDATA[
# C++ 函數與變數等級

## 函數的優點

### 1. 模組化
- 函數將程式分割為獨立模組，每個模組負責特定任務。
- 提高程式可讀性、易於除錯和維護，問題排查只需聚焦特定函數。

### 2. 程式碼重用
- 定義一次函數，可在程式多處呼叫，避免重複編寫相同程式碼。
- 減少冗余，提高可讀性與可維護性。

### 3. 抽象化
- 將複雜操作封裝為簡單函數呼叫，隱藏實現細節。
- 提供清晰介面，降低程式複雜度。

### 4. 組織與結構化
- 按邏輯任務組織程式碼，增強可讀性與可擴展性。
- 透過參數與回傳值傳遞資料，提升靈活性。

## 函數宣告

### 1. 函數寫在主函數後
需在主函數前宣告函數原型（prototype），以告知編譯器函數的存在。

**語法**：
```cpp
傳回值型態 函數名稱(引數型態1, 引數型態2, ...); // 函數原型

int main() {
    // 主函數內容
}

傳回值型態 函數名稱(引數型態1 引數1, 引數型態2 引數2, ...) {
    // 變數宣告
    // 語句主體
    return 運算式;
}
```

### 2. 函數寫在主函數前
無需額外宣告原型，直接定義函數。

**語法**：
```cpp
傳回值型態 函數名稱(引數型態1 引數1, 引數型態2 引數2, ...) {
    // 變數宣告
    // 語句主體
    return 運算式;
}

int main() {
    // 主函數內容
}
```

## 回傳值
函數可返回變數、常數或運算式。

**語法**：
```cpp
return 運算式; // 返回值
return;        // 無回傳值，適用於 void 函數
```

## 函數呼叫

### 1. 基本語法
```cpp
變數 = 函數名稱(參數); // 有回傳值的函數
函數名稱(參數);         // 無回傳值的函數
```

### 2. 主函數呼叫其他函數
```cpp
#include <iostream>
using namespace std;

void func1() {
    cout << "Function 1 called" << endl;
}

int main() {
    func1();
    return 0;
}
```

### 3. 函數間相互呼叫
函數可彼此呼叫，但需注意定義順序或使用原型。

**正確範例（使用原型）**：
```cpp
#include <iostream>
using namespace std;

void func1(); // 函數原型
void func2();

void func1() {
    cout << "Function 1 called" << endl;
    func2();
}

void func2() {
    cout << "Function 2 called" << endl;
}

int main() {
    func1();
    return 0;
}
```

**錯誤範例（順序錯誤）**：
```cpp
#include <iostream>
using namespace std;

void func1() {
    cout << "Function 1 called" << endl;
    func2(); // 錯誤：func2 未定義
}

void func2() {
    cout << "Function 2 called" << endl;
}

int main() {
    func1();
    return 0;
}
```

## inline 函數

### 1. 功能
- `inline` 函數類似巨集，編譯器將函數程式碼直接嵌入呼叫處，提升執行效率。
- 適合短小、頻繁呼叫的函數。

### 2. 定義格式
```cpp
inline 傳回值型態 函數名稱(型態1 引數1, 型態2 引數2, ...) {
    // 語句主體
}
```

### 3. 編譯器忽略 inline 的情況
- 函數內容過於複雜。
- 函數包含遞迴呼叫。
- 編譯器不支援 `inline`。

**範例**：
```cpp
#include <iostream>
using namespace std;

inline void print_star() {
    cout << "*************" << endl;
}

int main() {
    print_star();
    return 0;
}
```

## 變數等級
C++ 提供五種變數等級：`auto`、`static auto`、`extern`、`static extern` 和 `register`。

**範例宣告**：
```cpp
auto int i;        // 區域整數變數
extern char ch;    // 外部字元變數
static float f;    // 靜態浮點數變數
```

### 1. 區域變數（Local Variable）
- 也稱為自動變數（`automatic variable`）。
- 宣告於函數或區塊內，使用堆疊（stack）儲存，屬於動態變數。
- 生命週期：區塊開始時創建，結束時銷毀。

**範例**：
```cpp
void func() {
    int i;    // 區域變數，省略 auto
    char ch;  // 區域變數
}
```

**生命週期範例**：
```cpp
#include <iostream>
using namespace std;

void func() {
    // cout << a; // 錯誤：a 未定義
    int a = 1;
    cout << "a=" << a << endl; // 可使用 a
}

int main() {
    func();
    // cout << a; // 錯誤：a 未定義
    return 0;
}
```

**練習：觀察區域變數行為**
```cpp
#include <iostream>
using namespace std;

void func1() {
    int i = 10;
    cout << "in func1(), i=" << i << endl;
}

int main() {
    int i = 1;
    cout << "in main(), i=" << i << endl;
    func1();
    cout << "in main(), i=" << i << endl; // i 不受 func1 影響
    return 0;
}
```

### 2. 靜態區域變數
- 在編譯時分配固定記憶體，生命週期持續整個程式執行。
- 區塊結束後，值不會消失，保留至下次呼叫。

**範例**：
```cpp
static int i;
```

**練習：觀察靜態區域變數**
```cpp
#include <iostream>
using namespace std;

void func1() {
    static int i = 10;
    cout << "in func1(), i=" << i << endl;
    i += 10;
}

int main() {
    func1(); // i=10
    func1(); // i=20
    func1(); // i=30
    return 0;
}
```

### 3. 外部變數（External Variable）
- 也稱全域變數，宣告於函數外，作用範圍為整個程式。
- 可使用 `extern` 宣告，引用其他檔案或後續定義的變數。

**範例**：
```cpp
#include <iostream>
using namespace std;

int a = 1; // 全域變數

void func1() {
    a += 5;
    cout << "in func1(), a=" << a << endl;
}

void func2() {
    a += 10;
    cout << "in func2(), a=" << a << endl;
}

int main() {
    func1();
    func2();
    cout << "in main(), a=" << a << endl;
    return 0;
}
```

**注意**：
- 全域變數若宣告於所有函數之前，可省略 `extern`。
- `extern` 宣告不可包含初始值。

**錯誤範例**：
```cpp
void func1() {
    extern int a = 1; // 錯誤：extern 不可有初始值
    cout << "in func1(), a=" << a << endl;
}
```

**練習：區域變數與全域變數優先級**
```cpp
#include <iostream>
using namespace std;

int a = 0; // 全域變數

void func1() {
    a += 5;
    cout << "in func1(), a=" << a << endl; // 使用全域變數
}

void func2() {
    a += 10;
    cout << "in func2(), a=" << a << endl; // 使用全域變數
}

int main() {
    int a = 1000; // 區域變數優先
    func1();
    func2();
    cout << "in main(), a=" << a << endl; // 使用區域變數
    return 0;
}
```

### 4. 靜態外部變數
- 限於單一程式檔案使用，無法被其他檔案引用。

**範例**：
```cpp
#include <iostream>
using namespace std;

static int a;

void func1() {
    a = 10;
    if (a % 2 == 1) {
        cout << "is odd" << endl;
    } else {
        cout << "is even" << endl;
    }
}

int main() {
    func1();
    cout << "a=" << a << endl;
    return 0;
}
```

### 5. 暫存器變數
- 使用 CPU 暫存器儲存，提升存取速度。
- 由編譯器決定是否實際使用暫存器，通常可省略 `register` 關鍵字。

**範例**：
```cpp
register int i; // 建議編譯器使用暫存器
```

## 遞迴（Recursion）

### 1. 定義
遞迴函數是指函數呼叫自身，用於解決可分解為相似子問題的問題。

### 2. 原理
- **基本情況（Base Case）**：終止遞迴的條件，直接返回結果。
- **遞迴呼叫（Recursive Call）**：呼叫自身，處理較小規模的子問題。
- **問題分解**：將大問題拆解為相似但規模較小的子問題。
- **問題組合**：合併子問題的解以獲得最終結果。

**注意**：缺少基本情況可能導致無限遞迴，造成堆疊溢位（stack overflow）。

**圖示**：無限遞迴示意圖（來源：<https://www.freecodecamp.org/news/content/images/2019/09/is-this-you-need-to-be-stopped-2.png>）

### 3. 範例：階乘
計算 n!（n 的階乘）是遞迴的經典範例。

**正確範例**：
```cpp
#include <iostream>
using namespace std;

int fact(int a) {
    if (a <= 1) { // 基本情況
        return 1;
    }
    return a * fact(a - 1); // 遞迴呼叫
}

int main() {
    int a;
    do {
        cout << "輸入整數：";
        cin >> a;
    } while (a <= 0);
    cout << "1*2*...*" << a << "=" << fact(a) << endl;
    return 0;
}
```

**錯誤範例（原範例問題）**：
- 原範例 `fact(a * fact(a-1))` 語法錯誤，正確應為 `a * fact(a-1)`。
- 無明確基本情況，可能導致無限遞迴。
]]></content>
        <author>
            <name>作者名稱</name>
        </author>
        <category label="C++"/>
        <category label="初學"/>
        <category label="函式"/>
        <category label="變數"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[C++ 陣列基礎與應用]]></title>
        <id>http://localhost:3000/blog/arrary_c++</id>
        <link href="http://localhost:3000/blog/arrary_c++"/>
        <updated>2025-07-08T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[本文介紹 C++ 陣列的基本概念，包括一維、多維陣列的宣告與使用、記憶體表示法、字串、多項式與矩陣應用，以及陣列與指標的關係。]]></summary>
        <content type="html"><![CDATA[
# C++ 陣列（Array）

## 本章重點
1. 認識一維與多維陣列
2. 使用一維與多維陣列
3. 陣列與函數的結合
4. 了解陣列在記憶體中的表示法
5. 認識陣列的其他應用（如字串、多項式、矩陣）

## 簡介
陣列是一種儲存相同型態元素的容器，佔用連續記憶體空間。每個元素透過索引值（index）存取，索引從 0 開始，方便尋找與操作。陣列類似於水杯或書架，但每個儲存空間有編號，且記憶體位置連續。

**圖示**：陣列連續記憶體示意圖（來源：<https://back.tobosu.com/ke_file/2018-06-20/m_5b2a0e42d1c08.png>）

## 陣列的特性與優點
1. **連續記憶體**：佔用連續記憶體空間，存取效率高。
2. **有序結構**：表示有序資料序列。
3. **統一型態**：所有元素資料型態相同。
4. **存取方式**：支援隨機存取（透過索引）與循序存取（逐元素遍歷）。
5. **插入/刪除困難**：需挪移元素，效率較低。
6. **快速輸入/輸出**：透過索引與迴圈快速存取或輸出大量資料。

**範例：輸出陣列元素**
```cpp
#include <iostream>
using namespace std;
int main() {
    int A[5] = {1, 2, 3, 4, 5};
    for (int i = 0; i < 5; i++) {
        cout << A[i] << ' ';
    }
    cout << endl;
    return 0;
}
```

## 陣列的使用

### 1. 宣告
陣列與一般變數的差異在於記憶體配置方式。

| 變數宣告 | 陣列宣告 |
|----------|----------|
| 非連續記憶體配置 | 連續記憶體
配置，按順序排列 |

**不同維度陣列的宣告**：

| 一維陣列 | 二維陣列 | 多維陣列（以三維為例） |
|----------|----------|------------------------|
| `陣列名稱[大小];` | `陣列名稱[列數][行數];` | `陣列名稱[二維陣列數][列數][行數];` |

### 2. 陣列初始值設定

#### 2.1 一維陣列
```cpp
int a[3] = {1, 2, 3};       // 明確指定元素
int b[] = {1, 2, 3};        // 省略大小，自動推斷
int c[5] = {0};             // 所有元素初始化為 0
```

#### 2.2 二維陣列
{% raw %}
```cpp
int a[2][3] = {{1, 2, 3}, {4, 5, 6}}; // 2x3 陣列
int b[][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; // 省略列數
int c[2][3] = {0}; // 所有元素初始化為 0
```
{% endraw %}

#### 2.3 多維陣列
{% raw %}
```cpp
int a[2][3][4] = {
    {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}},
    {{12, 11, 10, 9}, {8, 7, 6, 5}, {4, 3, 2, 1}}
};
int b[][3][4] = {
    {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}},
    {{12, 11, 10, 9}, {8, 7, 6, 5}, {4, 3, 2, 1}}
}; // 省略第一維大小
int c[2][3][4] = {0}; // 所有元素初始化為 0
```
{% endraw %}

**其他初始化方法**：
- **迴圈初始化**：
  ```cpp
  int arr[5];
  for (int i = 0; i < 5; i++) {
      arr[i] = 0;
  }
  ```
- **memset**：
  ```cpp
  #include <cstring>
  int arr[5];
  memset(arr, 0, sizeof(arr)); // 將陣列初始化為 0
  ```

### 3. 陣列儲存方式
使用索引值指定儲存位置，索引可以是：
- 常數：`A[0] = 30;`
- 變數：`int x = 1; A[x] = 20;`
- 運算式：`A[x * 2] = 20;`
- 陣列元素：`int B[1] = {1}; A[B[0]] = 20;`

**範例**：
{% raw %}
```cpp
#include <iostream>
using namespace std;
int main() {
    int A[3];
    A[0] = 30; // 第一個位置存入 30
    int x = 1;
    A[x] = 20; // 第二個位置存入 20
    cout << A[0] << ' ' << A[1] << endl;
    return 0;
}
```

### 4. 記憶體中的表示法
陣列佔用連續記憶體空間，便於計算元素位址。

#### 4.1 一維陣列
設起始位址為 `Lo`，元素大小為 `d`（byte），索引值為 `i`，則：
- **位址計算公式**：`A[i] = Lo + i * d`

**範例 1**：
- 問題：若整數佔 4 byte，陣列 `A` 起始位址為 100，則 `A[5]` 的位址為何？
- 解答：`Lo = 100, d = 4, i = 5`  
  `A[5] = 100 + 5 * 4 = 120`

**範例 2**：
- 問題：若陣列 `A` 索引從 `L` 到 `U`，起始位址為 `Lo`，元素大小為 `d`，則 `A[i]` 的位址為何？
- 解答：`A[i] = Lo + (i - L) * d`

**範例 3**：
- 問題：若整數佔 2 byte，`A[10]` 起始位址為 200，則 `A[20]` 的位址為何？
- 解答：`Lo = 200, d = 2, i = 20, L = 10`  
  `A[20] = 200 + (20 - 10) * 2 = 200 + 20 = 220`

#### 4.2 二維陣列
設二維陣列為 `M × N`（M 列，N 行），起始位址為 `Lo`，元素大小為 `d`。
- **Row-major（以列為主）**：按列順序儲存，`A[i][j] = Lo + (i * N + j) * d`
- **Column-major（以行為主）**：按行順序儲存，`A[i][j] = Lo + (j * M + i) * d`

#### 4.3 多維陣列
以三維陣列 `A[i][j][k]` 為例，設第一維大小為 `u1`，第二維為 `u2`，第三維為 `u3`，起始位址為 `α`，則：
- **Row-major**：`A[i][j][k] = α + ((i-1) * u2 * u3 + (j-1) * u3 + (k-1)) * d`

**取得位址**：
- 使用 `&A[i]` 或 `&A[i][j][k]` 取得記憶體位址。

## 陣列的應用

### 1. 字串
C++ 中字串可用 `string` 或 `char[]` 表示，`char[]` 需以空字元 `'\0'` 結尾。

**範例**：
{% raw %}
```cpp
#include <iostream>
#include <string>
using namespace std;
int main() {
    char text1[] = {'h', 'e', 'l', 'l', 'o', '\0'};
    char text2[] = "hello";
    string text3 = "hello";
    cout << text1 << ' ' << text2 << ' ' << text3 << endl;
    return 0;
}
```

**注意**：
- C 語言無 `string` 型態，僅用 `char[]`。
- `'\0'`（ASCII 0）標記字串結束，佔 1 byte。

### 2. 多項式（Polynomials）
多項式表示為：`P(x) = A_m * x^m + A_{m-1} * x^{m-1} + ... + A_1 * x^1 + A_0 * x^0`

**儲存方式**：
- **依指數高低儲存係數**：按指數順序儲存所有係數，適用於非零項較多情況。
- **儲存非零項的係數與指數**：僅儲存非零項，節省空間，適用於稀疏多項式。

**範例 1：依指數高低儲存係數**
- 問題：`f(x) = 7x^4 + 5x^2 + 3x`
- 解答：
  ```cpp
  int poly[5] = {0, 3, 5, 0, 7}; // 索引 0~4 對應 x^0 ~ x^4
  ```

**範例 2：儲存非零項的係數與指數**
- 問題：`f(x) = 5x^100 + 1`
- 解答：
    {% raw %}
    ```cpp
    int poly[3][2] = {{2, 0}, {5, 100}, {1, 0}}; // {非零項數, {係數, 指數}}
    ```
    {% endraw %}

### 3. 矩陣（Matrices）
矩陣為 `m × n` 的二維陣列，m 表示列數，n 表示行數。

#### 3.1 矩陣轉置（Matrix Transposition）
`B[j][i] = A[i][j]`

**範例**：
{% raw %}
```cpp
#include <iostream>
using namespace std;

void Matrix_Transpose(int m, int n, int A[][3], int B[][2]) {
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            B[j][i] = A[i][j];
        }
    }
}

int main() {
    int A[2][3] = {{1, 2, 3}, {4, 5, 6}};
    int B[3][2];
    Matrix_Transpose(2, 3, A, B);
    return 0;
}
```
{% endraw %}

#### 3.2 矩陣相加（Matrix Addition）
`C[i][j] = A[i][j] + B[i][j]`

**範例**：
{% raw %}
```cpp
#include <iostream>
using namespace std;

void Matrix_Add(int m, int n, int A[][3], int B[][3], int C[][3]) {
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            C[i][j] = A[i][j] + B[i][j];
        }
    }
}

int main() {
    int A[2][3] = {{1, 2, 3}, {4, 5, 6}};
    int B[2][3] = {{7, 8, 9}, {10, 11, 12}};
    int C[2][3];
    Matrix_Add(2, 3, A, B, C);
    return 0;
}
```
{% endraw %}

#### 3.3 矩陣相乘（Matrix Multiplication）
`C[i][j] = Σ (A[i][k] * B[k][j])`

**範例**：
{% raw %}
```cpp
#include <iostream>
using namespace std;

void Matrix_Mul(int m, int n, int p, int A[][3], int B[][3], int C[][3]) {
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < p; j++) {
            C[i][j] = 0;
            for (int k = 0; k < n; k++) {
                C[i][j] += A[i][k] * B[k][j];
            }
        }
    }
}

int main() {
    int A[2][3] = {{1, 2, 3}, {4, 5, 6}};
    int B[3][2] = {{7, 8}, {9, 10}, {11, 12}};
    int C[2][2];
    Matrix_Mul(2, 3, 2, A, B, C);
    return 0;
}
```

{% endraw %}


#### 3.4 稀疏矩陣（Sparse Matrix）
多數元素為 0 的矩陣，直接用二維陣列儲存浪費空間。可用以下方式優化：
- 儲存非零項的 `{行, 列, 值}` 三元組。

**範例**（儲存稀疏矩陣）：
```cpp
#include <iostream>
using namespace std;

struct SparseElement {
    int row, col, value;
};

void StoreSparseMatrix(int m, int n, int A[][3], SparseElement sparse[], int& count) {
    count = 0;
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            if (A[i][j] != 0) {
                sparse[count].row = i;
                sparse[count].col = j;
                sparse[count].value = A[i][j];
                count++;
            }
        }
    }
}
```

## 其他陣列知識

### 1. 使用 `sizeof`
計算陣列或元素的大小（byte）。
```cpp
#include <iostream>
using namespace std;
int main() {
    int score[6];
    cout << sizeof(score) << endl;     // 24（6 個 int，假設 int 為 4 byte）
    cout << sizeof(score[2]) << endl; // 4（單個 int）
    return 0;
}
```

### 2. 計算陣列元素個數
```cpp
#include <iostream>
using namespace std;
int main() {
    int a[] = {3, 4, 6};
    int length = sizeof(a) / sizeof(int); // 3
    cout << "Length: " << length << endl;
    return 0;
}
```

### 3. 陣列與指標
陣列名稱是指向首元素的指標，支援指標運算。

**範例**：
```cpp
#include <iostream>
using namespace std;
int main() {
    int arr[4] = {1, 2, 3, 4};
    for (int i = 0; i < 4; i++) {
        cout << *(arr + i) << ' '; // 等同於 arr[i]
    }
    cout << endl;
    return 0;
}
```

**陣列作為函數參數**：
- 一維陣列：傳遞首元素地址。
- 二維陣列：需指定行數（第二維大小）。

**一維陣列範例**：
{% raw %}
```cpp
#include <iostream>
using namespace std;

void print(int arr[], int len) {
    for (int i = 0; i < len; i++) {
        cout << arr[i] << ' ';
    }
    cout << endl;
}

int main() {
    int a[3] = {1, 2, 3};
    print(a, 3); // 等同於 print(&a[0], 3)
    return 0;
}
```

**二維陣列範例**：
```cpp
#include <iostream>
using namespace std;

void print(int arr[][3], int i_len, int j_len) {
    for (int i = 0; i < i_len; i++) {
        for (int j = 0; j < j_len; j++) {
            cout << arr[i][j] << ' ';
        }
    }
    cout << endl;
}

int main() {
    int a[2][3] = {{1, 2, 3}, {4, 5, 6}};
    print(a, 2, 3);
    return 0;
}
```
{% endraw %}

**注意**：二維陣列作為參數時，行數（第二維）不可省略。

### 4. 陣列大小預留
為避免越界，宣告陣列時通常預留稍大空間。
```cpp
int arr[1005]; // 預留 1005 個元素，容納 1000 個資料
```

### 5. 陣列界限設置
C++ 不檢查索引越界，需自行確保索引有效，避免執行時錯誤（run-time error）。

**範例：使用宏定義陣列大小**：
```cpp
#define MAX 5
int arr[MAX];
```

## 延伸練習題
1. **a015. 矩陣的翻轉**：<https://zerojudge.tw/ShowProblem?problemid=a015>
2. **a022. 迴文**：<https://zerojudge.tw/ShowProblem?problemid=a022>
3. **a038. 數字翻轉**：<https://zerojudge.tw/ShowProblem?problemid=a038>

]]></content>
        <author>
            <name>作者名稱</name>
        </author>
        <category label="C++"/>
        <category label="Array"/>
        <category label="陣列"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[C++ 程式結構]]></title>
        <id>http://localhost:3000/blog/Statements_c++</id>
        <link href="http://localhost:3000/blog/Statements_c++"/>
        <updated>2025-07-08T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[本文介紹 C++ 程式語言的結構，包括循序、選擇和重複結構，以及 if-else、for、while、do-while、switch 與條件運算子。]]></summary>
        <content type="html"><![CDATA[
# C++ 程式結構

## 程式結構概覽

C++ 程式結構分為三種類型：循序結構、選擇結構和重複結構。

| 循序結構（Sequence Structure） | 選擇結構（Selection Structure） | 重複結構（Iteration Structure） |
| --- | --- | --- |
| 程式碼從上至下依序執行 | 根據條件決定執行哪些語句 | 根據條件重複執行語句，控制執行次數 |
| 簡單直接，無條件判斷 | 包括 `if`、`if-else` 和 `switch` 語句 | 包括 `for`、`while` 和 `do-while` 迴圈 |

## if-else 語句

當條件成立時，執行 `if` 語句主體；若不成立，則依序檢查 `else if` 條件；若所有條件均不成立，執行 `else` 語句主體。一旦某條件成立，後續條件不再檢查。

**語法**：

```cpp
if (判斷條件) {
    語句主體;
}
else if (判斷條件) {
    語句主體;
}
else {
    語句主體;
}
```

**練習：判斷輸入回答是否正確**

```cpp
#include <iostream>
#include <string>
using namespace std;
int main() {
    string ans;
    cout << "50可以被5整除嗎？yes or no?" << endl;
    cin >> ans;
    if (ans == "yes") {
        cout << "答對了" << endl; // 單行語句可省略大括號
    }
    else if (ans == "no") {
        cout << "答錯了" << endl;
    }
    else {
        cout << "不符合問題的回答" << endl; // 防呆設計
    }
    return 0;
}
```

## 巢狀 if 語句

在 `if` 語句中嵌套另一個 `if` 語句，只有當外層和內層條件均成立時，才執行內層語句主體。

**語法**：

```cpp
if (判斷條件1) {
    if (判斷條件2) {
        語句主體; // 條件1和條件2均滿足時執行
    }
    // 其他語句
}
```

## for 迴圈

用於固定次數的重複執行。

**語法**：

```cpp
for (迴圈初始值; 判斷條件; 增減量) {
    迴圈主體;
}
```

**執行流程**：

1. 設定迴圈控制變數的初始值。
2. 檢查判斷條件是否成立，若成立則執行迴圈主體。
3. 根據增減量更新控制變數，回到步驟 2。

**練習：印出 1 到 100**

```cpp
#include <iostream>
using namespace std;
int main() {
    for (int i = 1; i <= 100; i++) {
        cout << i << ' ';
    }
    cout << endl;
    return 0;
}
```

## while 迴圈

在條件成立時重複執行迴圈主體。

**語法**：

```cpp
while (判斷條件) {
    迴圈主體;
    增減量; // 視條件決定是否需要
}
```

**執行流程**：

1. 在進入迴圈前設定控制變數初始值。
2. 檢查判斷條件是否成立，若成立則執行迴圈主體。
3. 更新控制變數，回到步驟 2。

**練習：改寫 for 迴圈印出 1 到 100**

```cpp
#include <iostream>
using namespace std;
int main() {
    int i = 1;
    while (i <= 100) {
        cout << i << ' ';
        i++;
    }
    cout << endl;
    return 0;
}
```

**補充：持續讀入數字並相加**

```cpp
#include <iostream>
using namespace std;
int main() {
    int a, b;
    while (cin >> a >> b) {
        cout << a + b << endl;
    }
    return 0;
}
```

**補充：持續讀入字串直到遇到 EOF**

```cpp
#include <iostream>
#include <string>
using namespace std;
int main() {
    string s;
    while (cin >> s) {
        if (s == "EOF") {
            break;
        }
        cout << s << endl;
    }
    return 0;
}
```

## do-while 迴圈

先執行迴圈主體，再檢查條件，至少執行一次。

**語法**：

```cpp
do {
    迴圈主體;
    增減量;
} while (判斷條件);
```

**執行流程**：

1. 設定控制變數初始值。
2. 執行迴圈主體。
3. 檢查條件，若成立則更新控制變數並回到步驟 2。

**練習：從 0 累加到 n**

```cpp
#include <iostream>
using namespace std;
int main() {
    int i = 0, sum = 0, n;
    cin >> n;
    do {
        sum += i;
        i++;
    } while (i <= n);
    cout << "sum=" << sum << endl;
    return 0;
}
```

## 巢狀迴圈

迴圈中嵌套另一個迴圈。

**語法**：

```cpp
for (...) {
    for (...) {
        // 語句
    }
}
```

**練習：九九乘法表**

```cpp
#include <iostream>
using namespace std;
int main() {
    for (int i = 1; i < 10; i++) {
        for (int j = 1; j < 10; j++) {
            cout << i << "*" << j << "=" << i * j << " ";
        }
        cout << endl;
    }
    return 0;
}
```

## break 與 continue 語句

### break 語句

立即跳出迴圈，執行迴圈外的語句。

**練習：印出 1 到 n（n 不確定，假設小於 100）**

```cpp
#include <iostream>
using namespace std;
int main() {
    int n;
    cin >> n;
    for (int i = 1; i <= 100; i++) {
        if (i == n) {
            break;
        }
        cout << i << ' ';
    }
    cout << endl;
    return 0;
}
```

### continue 語句

跳過當前迴圈剩餘語句，進入下一次迴圈。

**練習：印出 1 到 10，跳過 4 的倍數**

```cpp
#include <iostream>
using namespace std;
int main() {
    for (int i = 1; i <= 10; i++) {
        if (i % 4 == 0) {
            continue;
        }
        cout << i << ' ';
    }
    cout << endl;
    return 0;
}
```

## switch 語句

根據運算式結果選擇對應的 `case` 執行，需用 `break` 終止，否則繼續執行後續 `case`。各 `case` 的選擇值不可重複。

**語法**：

```cpp
switch (運算式) {
    case 選擇值1:
        語句主體;
        break;
    case 選擇值2:
        語句主體;
        break;
    // ...
    default:
        語句主體;
}
```

**註記**：`switch` 可由 `if-else` 替代，後者更直觀且無需 `break`。

**練習：根據農曆月份判斷季節**

```cpp
#include <iostream>
using namespace std;
int main() {
    int month;
    cin >> month;
    switch (month) {
        case 1:
        case 2:
        case 3:
            cout << "春天" << endl;
            break;
        case 4:
        case 5:
        case 6:
            cout << "夏天" << endl;
            break;
        case 7:
        case 8:
        case 9:
            cout << "秋天" << endl;
            break;
        case 10:
        case 11:
        case 12:
            cout << "冬天" << endl;
            break;
        default:
            cout << "無效的月份" << endl;
    }
    return 0;
}
```

## 條件運算子（Conditional Operator）

簡化 `if-else` 的三元運算子。

**語法**：

```cpp
傳回值 = (判斷條件) ? 運算式1 : 運算式2;
```

- 若條件為 `true`，執行運算式1；否則執行運算式2。

**練習：找出 a 和 b 的最小值**

```cpp
#include iostream;
using namespace std;
int main() {
int a = 2, b = 10;
int min = (a &lt; b) ? a : b;
cout &lt;&lt; "min=" &lt;&lt; min &lt;&lt; endl;
return 0;
}
```
]]></content>
        <author>
            <name>作者名稱</name>
        </author>
        <category label="C++"/>
        <category label="初學"/>
        <category label="程式結構"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[C++ 運算式與運算子]]></title>
        <id>http://localhost:3000/blog/Operators_c++</id>
        <link href="http://localhost:3000/blog/Operators_c++"/>
        <updated>2025-07-08T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[本文介紹 C++ 中的運算式與運算子，包括設定、一元、算術、關係、遞增遞減、邏輯、位元邏輯與括號運算子。]]></summary>
        <content type="html"><![CDATA[

# C++ 運算式與運算子

## 運算式
運算式由**運算元（operand）**與**運算子（operator）**組成，用於執行計算或邏輯操作。運算式的結果具有特定資料型態。

### 範例
以下均為合法的 C++ 運算式：
```cpp
-2;             // 一元運算子「-」與常數 2 組成
age + 2;        // 變數 age、算術運算子 + 與常數 2 組成
a * b * c * (d / 3 - 1); // 變數、常數與多個運算子組成
```

## 運算子

### 1. 設定運算子
用於賦值，將右邊的值設定給左邊的變數。

| 運算子 | 意義 |
|--------|------|
| `=`    | 將右邊的值設定給左邊的變數 |

**範例**：
```cpp
int x = 10; // 將 10 設定給變數 x
```

### 2. 一元運算子
僅需一個運算元的運算子。

| 運算子 | 意義 |
|--------|------|
| `+`    | 正號（通常省略） |
| `-`    | 負號 |
| `!`    | 邏輯否定（布林值取反） |
| `~`    | 位元取補數（將 1 變 0，0 變 1） |

**範例**：
```cpp
+63;       // 正 63
int b = 5;
-b;        // 負 b，結果為 -5
~b;        // 對 b 進行位元取補數
int a = -b; // 將 -b 的值設定給 a
```

### 3. 算術運算子
用於數學運算。

| 運算子 | 意義 |
|--------|------|
| `+`    | 加法 |
| `-`    | 減法 |
| `*`    | 乘法 |
| `/`    | 除法 |
| `%`    | 取餘數（僅適用於整數） |

**練習：整數除法與浮點數除法**
```cpp
#include <iostream>
using namespace std;
int main() {
    int a = 10, b = 3;
    int result = a / b;      // 結果為 3（整數除法，捨去小數）
    float c = 10.0, d = 3.0;
    float result2 = c / d;   // 結果為 3.33333（浮點數除法）
    cout << "int: " << result << ", float: " << result2 << endl;
    return 0;
}
```

**算術與設定運算子的結合**
結合算術與設定運算子可簡化程式碼，常用的複合運算子包括 `+=`, `-=`, `*=`, `/=`, `%=`。

**練習：複合運算子**
```cpp
#include <iostream>
using namespace std;
int main() {
    int a = 100, b = 15;
    cout << "a=" << a << ", b=" << b << endl;
    a -= b; // 等價於 a = a - b
    cout << "after a-=b, a=" << a << ", b=" << b << endl;
    return 0;
}
```

### 4. 關係運算子
用於比較兩個運算元，通常搭配條件語句，返回布林值（`true` 或 `false`）。

| 運算子 | 意義 |
|--------|------|
| `>`    | 大於 |
| `<`    | 小於 |
| `>=`   | 大於等於 |
| `<=`   | 小於等於 |
| `==`   | 等於 |
| `!=`   | 不等於 |

### 5. 遞增與遞減運算子
用於將變數值增加或減少 1。

| 運算子 | 意義 |
|--------|------|
| `++`   | 遞增，變數值加 1 |
| `--`   | 遞減，變數值減 1 |

**`i++` 與 `++i` 的區別**：
- `i++`（後置遞增）：先使用 `i` 的值，再將 `i` 加 1。
- `++i`（前置遞增）：先將 `i` 加 1，再使用新值。
- `--i` 和 `i--` 同理。

**練習：後置遞增運算子**
```cpp
#include <iostream>
using namespace std;
int main() {
    int a = 10;
    cout << "a=" << a << endl;
    cout << "a++*2=" << (a++ * 2) << endl; // 先計算 a*2，再將 a 加 1
    cout << "a=" << a << endl;             // a 已變為 11
    return 0;
}
```

**練習：前置遞增運算子**
```cpp
#include <iostream>
using namespace std;
int main() {
    int a = 10;
    cout << "a=" << a << endl;
    cout << "++a*2=" << (++a * 2) << endl; // 先將 a 加 1，再計算 a*2
    cout << "a=" << a << endl;             // a 已變為 11
    return 0;
}
```

### 6. 邏輯運算子
用於操作布林值，結合多個條件。

| 運算子 | 名稱       | 意義 |
|--------|------------|------|
| `!`    | NOT        | 取反（`true` 變 `false`，反之亦然） |
| `&`    | AND        | 兩運算元均為 `true` 時返回 `true` |
| `|`    | OR         | 任一運算元為 `true` 時返回 `true` |
| `^`    | XOR        | 兩運算元不同時返回 `true` |
| `&&`   | AND ALSO   | 同 `&`，具短路求值特性 |
| `||`   | OR ELSE    | 同 `|`，具短路求值特性 |

**短路求值**：
- `||`：若第一運算元為 `true`，則不評估第二運算元，直接返回 `true`。
- `&&`：若第一運算元為 `false`，則不評估第二運算元，直接返回 `false`。

### 7. 位元邏輯運算子
對變數的二進位位元進行操作。

| 運算子 | 名稱 | 意義 |
|--------|------|------|
| `~`    | NOT  | 位元取補數（1 變 0，0 變 1） |
| `&`    | AND  | 兩位元均為 1 時返回 1 |
| `|`    | OR   | 任一位元為 1 時返回 1 |
| `^`    | XOR  | 兩位元不同時返回 1 |
| `>>`   | 右移 | 位元右移，左邊補 0（等價於除以 2） |
| `<<`   | 左移 | 位元左移，右邊補 0（等價於乘以 2） |

### 8. 括號運算子
用於控制運算式的優先順序。

| 運算子 | 意義 |
|--------|------|
| `()`   | 優先計算括號內的運算式 |

**範例：括號的影響**
```cpp
int result1 = 8 - 2 * 3 + 7 * 6;     // 結果為 44（依優先順序計算）
int result2 = 8 - 2 * (3 + 7) * 6;   // 結果為 -112（括號改變優先順序）
```

### 9. 運算子優先順序
運算子的執行順序由優先級決定，優先級高的先執行。以下是常見運算子的優先順序（由高到低）：

| 優先級 | 運算子 | 說明 | 結合方向 |
|--------|--------|------|----------|
| 1      | `()`   | 括號 | 左到右 |
| 2      | `++`, `--`, `+`, `-`, `!`, `~` | 遞增、遞減、一元正負、邏輯/位元 NOT | 右到左 |
| 3      | `*`, `/`, `%` | 乘、除、取餘 | 左到右 |
| 4      | `+`, `-` | 加、減 | 左到右 |
| 5      | `<<`, `>>` | 位元左移、右移 | 左到右 |
| 6      | `>`, `<`, `>=`, `<=` | 關係運算子 | 左到右 |
| 7      | `==`, `!=` | 等於、不等於 | 左到右 |
| 8      | `&` | 位元 AND | 左到右 |
| 9      | `^` | 位元 XOR | 左到右 |
| 10     | `|` | 位元 OR | 左到右 |
| 11     | `&&` | 邏輯 AND | 左到右 |
| 12     | `||` | 邏輯 OR | 左到右 |
| 13     | `=` | 設定運算子 | 右到左 |

**注意**：使用括號可明確指定運算順序，避免依賴優先級造成的歧義。

## 型態轉換

### 1. 隱性資料型態轉換（Implicit Type Conversion）
C++ 會自動進行型態轉換，遵循以下規則：
1. 轉換前後的資料型態相容。
2. 轉換後的型態表示範圍大於轉換前的型態（例如，`short` 轉為 `int`）。
3. 轉換僅影響當前運算式，不改變變數本身。
4. 以確保資料精度不損失為原則。

**範例**：
```cpp
#include <iostream>
using namespace std;
int main() {
    int a = 45;
    float b = 2.3f;
    cout << "a=" << a << ", b=" << b << endl;
    cout << "a/b=" << a / b << endl; // a 自動轉為 float，結果為 19.5652
    return 0;
}
```

### 2. 顯性資料型態轉換（Explicit Type Conversion）
也稱為強制型態轉換，透過指定型態進行轉換。

**語法**：
```cpp
(欲轉換的資料型態) 變數名稱;
```

**範例**：
```cpp
float a = 1.0;
int b = (int)a; // 將 a 轉為 int，b = 1
```

**練習：顯性型態轉換**
```cpp
#include <iostream>
using namespace std;
int main() {
    int a = 36, b = 7;
    cout << "a=" << a << ", b=" << b << endl;
    cout << "a/b=" << a / b << endl;              // 結果為 5（整數除法）
    cout << "a/b=" << (float)a / b << endl;       // 結果為 5.14286（轉為浮點數）
    return 0;
}
```

### 3. 運算式的型態轉換規則
當運算式中的運算元型態不一致時，C++ 會自動進行型態轉換：
1. 佔用位元組較少的型態轉為位元組較多的型態（例如，`short` 轉 `int`）。
2. 若運算式中包含 `double` 型態，另一運算元轉為 `double`。
3. 布林型態（`bool`）不可轉換為其他型態。

**範例**：
```cpp
#include <iostream>
using namespace std;
int main() {
    char ch = 'X';   // ASCII 值為 88
    short s = -5;
    int i = 6;
    float f = 9.7f;
    double d = 1.76;
    cout << "(s*ch)-(d/f)*(i+f)=";
    cout << (s * ch) - (d / f) * (i + f) << endl; // 型態自動轉換
    return 0;
}
```
]]></content>
        <author>
            <name>作者名稱</name>
        </author>
        <category label="C++"/>
        <category label="初學"/>
        <category label="運算式與運算子"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[C++ - 簡單介紹]]></title>
        <id>http://localhost:3000/blog/Introduction_c++</id>
        <link href="http://localhost:3000/blog/Introduction_c++"/>
        <updated>2025-07-08T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[本文介紹 C++ 的歷史、特色、程式結構、流程圖與基本編譯執行方式。]]></summary>
        <content type="html"><![CDATA[
# C++ 程式語言介紹

## 歷史
1. **C語言**：1972年由丹尼斯·里奇（Dennis Ritchie）在貝爾實驗室開發，是一種結構化程式語言。
2. **C++語言**：1980年代由比雅尼·斯特勞斯特魯普（Bjarne Stroustrup）開始發展。
   - 將物件導向（Object-Oriented Programming, OOP）概念融入C語言。
   - 最初稱為「C with Classes」。

## 特色
C++ 是由 C 語言延伸而來的通用程式語言，具有以下主要特色：

1. **向下相容 C 語言**：
   - C++ 包含 C 語言的所有功能，幾乎所有的 C 程式碼都可以在 C++ 中執行。
2. **物件導向程式設計（OOP）**：
   - **封裝**：將資料與操作資料的函式封裝成類別，保護資料並提高程式模組化。
   - **繼承**：允許新類別基於現有類別擴展功能，實現程式碼重用。
   - **多型**：同一操作可應用於不同類型的物件，增加程式靈活性。
3. **靈活的流程控制**：
   - 提供多種控制結構（如條件語句、迴圈），支援複雜的程式邏輯。
4. **高效能與可攜性**：
   - C++ 程式需經過編譯（Compile），執行效率高於直譯式語言（如 Basic）。
   - 可攜性佳，僅需少量修改即可在不同作業系統上執行。
5. **程式碼重用**：
   - 透過繼承與模板，程式碼可被重複使用，減少開發時間與成本。

## 流程圖
流程圖是用來表示程式執行流程的圖形化工具，常用於設計與理解程式邏輯。

### 1. 常用符號
| 符號形狀 | 意義 |
|----------|------|
| 橢圓 | 程式開始或結束 |
| 矩形 | 處理步驟 |
| 菱形 | 條件判斷 |
| 箭頭 | 流程方向 |

### 2. 範例
以下是一個簡單流程圖，展示檢查數字是否為正數的邏輯：
```
開始 → 輸入數字 → 數字 > 0？ → 是：顯示「正數」 / 否：顯示「非正數」 → 結束
```

## 程式的編譯與執行
1. **編譯**：C++ 程式需透過編譯器轉換為機器碼，生成可執行檔案。
2. **執行**：執行編譯後的可執行檔案，顯示程式結果。
3. **工具**：常見編譯器包括 GCC、Clang、MSVC 等。

## 程式基本結構

### 1. 主函數 `main()`
- 每個 C++ 程式必須有且僅有一個 `main()` 函數，作為程式執行入口。
- 語法：
  ```cpp
  int main() {
      // 程式碼
      return 0; // 表示程式正常結束
  }
  ```
- `return 0` 表示程式成功執行，非零值表示異常。

### 2. 預處理指令 `#`
- 以 `#` 開頭的指令由前置處理器在編譯前處理。
- 常見指令：
  - `#include <iostream>`：包含輸入輸出流相關函數。
  - `#include <cstdlib>`：包含標準函數庫（如 `system()`）。

### 3. 命名空間 `std`
- `std` 是 C++ 標準庫的命名空間，包含 `cin`、`cout` 等功能。
- 使用方式：
  - 直接使用：`std::cout`。
  - 宣告命名空間：`using namespace std;` 後可省略 `std::`。
  - 示例：
    ```cpp
    #include <iostream>
    using namespace std;
    int main() {
        cout << "Hello, World!" << endl;
        return 0;
    }
    ```

### 4. 標頭檔（Header Files）
- 標頭檔包含函數、類別等定義，位於程式碼開頭。
- 比較：
  | 狀態 | 範例 |
  |------|------|
  | 含括前 | 無法使用 `cout`、`cin` 等功能 |
  | 含括後 | 可使用標準庫功能，如 `std::cout << "Hello";` |

### 5. 註解
- 註解用於說明程式邏輯或暫時停用程式碼，不會被編譯。
- 類型：
  - 單行註解：`// 這是單行註解`
  - 多行註解：
    ```cpp
    /* 這是
       多行註解 */
    ```

### 6. 大括號與區塊
- 區塊由 `{` 開始，`}` 結束，包含一組指令。
- 每條指令以分號 `;` 結尾。

### 7. 暫停指令 `system("pause")`
- **用途**：在程式結束前暫停，允許使用者查看執行結果。
- **語法**：
  ```cpp
  system("pause"); // 等待使用者按鍵後關閉視窗
  ```
- **注意**：僅適用於 Windows 環境，其他系統可能需要替代方案（如 `cin.get()`）。

## 錯誤分類
1. **語法錯誤（Syntax Error）**：
   - 程式碼不符合 C++ 語法規則，如缺少分號、括號不匹配。
   - 範例：`cout << "Hello"`（缺少 `;`）。
2. **語意錯誤（Semantic Error）**：
   - 語法正確，但執行結果不符合預期。
   - 範例：計算 `a + b` 時，誤用 `a - b`。

## ANSI/ISO C++ 標準
C++ 標頭檔類型：
1. **C 語言標頭檔**：以 `.h` 結尾（如 `<stdio.h>`）。
2. **C++ 標頭檔**：以 `.h` 結尾（如 `<iostream.h>`，早期使用）。
3. **新標準標頭檔**：無副檔名（如 `<iostream>`）。
4. **C 語言移植標頭檔**：無副檔名，字首加 `c`（如 `<cstdio>`）。

新版 C++ 需使用 `using namespace std;` 來指定命名空間。
]]></content>
        <author>
            <name>作者名稱</name>
        </author>
        <category label="C++"/>
        <category label="初學"/>
        <category label="簡介"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[圖片功能示例文章]]></title>
        <id>http://localhost:3000/blog/example_with_images</id>
        <link href="http://localhost:3000/blog/example_with_images"/>
        <updated>2025-01-15T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[這是一篇展示如何在文章中使用圖片功能的示例文章，包含各種圖片使用方式。]]></summary>
        <content type="html"><![CDATA[
# 圖片功能示例文章

這篇文章展示了如何在 markdown 文章中使用圖片功能。

## 基本圖片插入

你可以使用標準的 markdown 語法插入圖片：

```markdown
![圖片描述](圖片URL)
```

例如：

![網站圖標](/images/icon.jpg)

## 帶標題的圖片

你也可以為圖片添加標題，標題會顯示為圖片說明：

```markdown
![圖片描述](圖片URL "圖片標題")
```

例如：

![我的照片](/images/my.jpg "這是我的照片")

## 網路圖片

你也可以使用網路上的圖片：

![範例圖片](https://via.placeholder.com/600x300/4F46E5/FFFFFF?text=範例圖片 "這是一張範例圖片")

## 圖片功能特色

1. **響應式設計**：圖片會自動適應不同螢幕大小
2. **燈箱效果**：點擊圖片可以放大檢視
3. **載入動畫**：圖片支援懶載入，提升頁面載入速度
4. **圖片說明**：支援圖片標題作為說明文字
5. **美觀樣式**：圖片有圓角、陰影等美化效果

## 使用建議

- 建議將圖片放在 `public/images/` 資料夾中
- 使用相對路徑 `/images/檔名.jpg` 引用圖片
- 為圖片添加有意義的 alt 文字，提升無障礙性
- 可以使用圖片標題功能添加說明文字
- 在 Frontmatter 中添加 `image` 欄位，將圖片設為背景圖片
- 在 Frontmatter 中添加 `category` 欄位（如：information、tutorial、技術等），用於分類

## Frontmatter 範例

```yaml
---
title: 文章標題
date: "2025-01-15"
description: 文章描述
tags: ["標籤1", "標籤2"]
category: information    # 用於分類歸檔
image: /images/example.jpg  # 用於首頁焦點和文章詳情背景圖片
published: true
---
```

## 新功能介紹

### 首頁佈局
- **焦點推薦**：首頁最新文章會以大卡片形式展示，帶有背景圖片
- **文章網格**：其他文章以 3x3 網格展示，支援分頁

### 文章歸檔
- 使用分類抽屜菜單快速篩選不同分類的文章
- 每個文章卡片都展示分類標籤、發佈日期和預計閱讀時間

### 文章詳情
- 背景圖片會以半透明形式顯示在文章左側
- 圖片為固定位置，不會跟著頁面滾動
]]></content>
        <author>
            <name>作者名稱</name>
        </author>
        <category label="示例"/>
        <category label="圖片"/>
        <category label="功能展示"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[題解ZJ - a225.明明愛排列]]></title>
        <id>http://localhost:3000/blog/PE_zj_a225</id>
        <link href="http://localhost:3000/blog/PE_zj_a225"/>
        <updated>2024-02-21T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[ZeroJudge a225 明明愛排列的題解與完整 C++ 程式碼。]]></summary>
        <content type="html"><![CDATA[
# 題目[a225. 明明愛排列](https://zerojudge.tw/ShowProblem?problemid=a225) 
完整程式碼:
```cpp
#include<bits/stdc++.h>
using namespace std;

int arr[100000];
int ans[100000];
int a=0,b=0;


int main()
{
  while(cin>>a)
  {
    int num=0;
    for(int i=0;i<a;i++)
    {
      cin>>arr[i];
    }
    sort(arr,arr+a,greater<int>());
    for(int i=0;i<=9;i++)
    {
          for(int j=0;j<a;j++)
          {
            if(arr[j]%10==i)
            {
            ans[num]=arr[j];
            num+=1;
            }
          }
    }

    for(int i=0;i<a;i++)
    {
      cout<<ans[i]<<" ";
    }
    cout<<'\n';
  }
return 0;
}
```
]]></content>
        <author>
            <name>作者名稱</name>
        </author>
        <category label="C++"/>
        <category label="ZJ題解"/>
        <category label="ZeroJudge"/>
    </entry>
</feed>