---
# System prepended metadata

title: C++語法

---

# <font color="1d206e">**C++程式語言教學講義**
    
## **海山高中 資訊研究社第六屆** </font>
> ####    作者 : 教學 曾沛芝


---

# 壹、基礎
## 零.標頭檔
```c=
#include<bits/stdc++.h>
using namespace std;
int main(){
    //這裡寫程式碼
}
```
## 一、輸出輸入
### 1.輸入（cin)
```c=
int x;
cin >> x;
```
### 2.輸出（cout)
```c=
int x;
cout << x;
```
### 3.換行（endl vs '\n'）
```c=
cout << endl;
cout << "\n"

cout << "apple\n"
//兩者作用一樣，但'\n'適合加在原本就要輸出字元或字串後面，比較快速
```
### 4.加空格
```c=
cout << " ";
```
> 很直覺，用包字元的雙引號包住空格就好了
## 二、自定義變數
### 0.宣告地點
未完待續
### 1.常見類型
```c=
int x = 10; // 整數

string x = "apple"; // 字串

char x = 'A'; // 字元

double x = 3.14; // 雙精準浮點數
float x = 3.14; // 單精準浮點數

bool x = true; // 布林值只有true/false
```
### 2.需要套用值 <font color="#f00">  過大</font>（定義變數時用 long long）
```c=
long long x = 2000000;
```
### 3.布林值
* 宣告方法 : 
```c=
bool a = true;
```
* 布林值不像整數變數`int`或是字串變數`string`可以自由放東西進去，<font color="red">布林值只會是兩個值 2 選 1 ，
真 ( true ) or  假 ( false )。</font>
（0 代表 false，1 代表 true，直接打英文也可以）
### 4.鎖定變數
```c=
const int x = 10; //之後x不能更改
```
### 5.自動推導(auto)
```c=
auto x = 10    //推斷為 int 
auto y = 3.14    //推斷為 double
```
> 不建議使用auto定義，電腦可能判斷錯

### 6.陣列變數
> 一次存取多個相同型態的值
```c=
int a[3] = {1,2,3};
vector<int> a(3);

//以下二維陣列

int a[2][3] ={{1,2,3}{4,5,6}};
vector<vector<int>> a(2,vector<int>(3));
```
> 一般陣列對比vector的差別，請看之後章節

### <font color="1d206e">7.**結構(struct)**</font>
<font color="blue">適用需要將多種</font> <font color="red">不同類型資料 </font><font color="blue">處存於同一處時</font>
* 例如 : 一個學生同時有他的的名稱、年齡、成績
就可以這樣寫
```c=
struct Student{
    string name = {};
    int age;
    float score;
    //都保持空白
}
```
* 而要如何呼叫呢?
首先在`main`主函數裡面用<font color="blue">剛剛寫的 : `struct Student`的名稱</font>[`Student`]去定義一個變數

```c=
int main(){
    
    Student s1[5];    
    
    //創建型態為Student的陣列
    //意即每一格都有name age score三種資料
}
```
> 這其實跟`int string float`是一樣的用法，只不過你用`struct`自己創建了一個
* 要如何呼叫裡面`struct`的小點?
```c=
    s1[0].name = "Tom";
    s1[0].age = 19;
    s1[0].score = 59.9;
    
    //用 s1[0](變數名稱).name(結構內變數名稱)呼叫
}
```
### 8.如果 ( if )
```c=
if(//條件){
    //程式碼
}
```
* 如果達成括弧`()`內條件，就執行大括弧`{}`內程式碼。
* 如需多項條件比較如下 : 
**else 否則**
```c=
if(//條件){
    //程式碼
}
else if(//條件){
    //程式碼
}
else if(//條件){
    //程式碼
}
else{
    //程式碼
}
```
* `else if`代表<font color = "red">其他，意即如果上面沒有達成才往下</font>
* `else`最後一個沒有條件，如果上面的`if`和`else if`都沒有達成才會執行`else`
### 9. for迴圈
* i每一輪數值不同
* 可自定義幾輪
```c=
for(int i = 0;i < 2;i ++){
    //程式碼
}
```
* 以上為一個執行2次的迴圈，執行方法如下 :  
1. 第一輪判斷 : i = 0，i有小於2，所以執行一次，下一輪i++。
1. 第二輪判斷 : i = 0 + 1 = 1，i有小於2，所以執行一次，下一輪i++。
1. 第三輪判斷 : i = 1 + 1 = 2，i<font color = "red">沒有</font>小於2，所以不執行，結束迴圈
* <font color = "blue">由此可知此迴圈
1. 會跑`2`次
2. 第一次的時候`i = 0`第二次的時候`i = 1`</font>
---
### 10. while迴圈
```c=
while(//條件){
    //要執行程式    
}
```
### 11.條件
* 列舉一些常見的條件在底下 : 
```c=
a > b
a >= b
a == b //a等於b?
a != b //a不等於b?

a > b && a > c //a > b "且" a > c(兩個同時達成才執行)
a > b || a > c // "或" (只達成一個就執行)
```
* 如果變數是布林值 ( **bool** )，可以直接寫變數名稱。
```c=
bool apple = true;

if(apple){//apple是否為真

}
if(!apple)}//apple是否為假
    
}
```
* 一個布林值apple，值為true。
* `if(apple)`代表:如果apple是`true`就執行
* `if(!apple)`代表:如果apple是`false`就執行


---

# 貳、判斷
## 一、字串 判斷 (string s;)
都以`string s;` 舉例
### 1.讀取<font color="red">整行</font>字串 (getline)
* cin有一個很大的特點，會在使用者輸入<font color="blue">空白鍵或是enter來當成結束的依據</font>
例如 : 想讓 "Teddy Liu" 這是一個字串，存在同一個變數中時，`string s; cin >> s `就做不到。<font color="red">電腦會自動將Teddy和Liu分開儲存</font>，因為中間含有空格。

*  若想將字串 "Teddy Liu" 存在一個變數中，請看底下示範
```c=
string s; //不可以
getline(cin,s); //可存含有空格字串
```
> 需要注意的是，`getline`只會把enter鍵當成結束的依據
### 2.判斷字串有幾個字母
* 例如:"apple"有5個，"toy"有3個
```c=
string s = "apple";
x = s.size();

cout << x;
//會得到 5
```
其他寫法為 :
```c=
int x;
x = s.length();
x = s.size();
```
* 兩者同樣意思，記自己喜歡的就好
### 3.`s[i]`(取字串中第i個字母)
```c=
string s = "apple"
char x = s[0] //"apple"的第一位字母'a'
char y = s[4] //"apple"的第五位字母'e'
```
> 注意! <font color="red">第一位從s[0]取
</font>若s陣列大小為5格，最後一位只到s[4]，<font color="red">s[5]不存在</font>，若引用會爆錯。
### 4.從第x位開始取y個 (s.substr(x,y))
```c=
string s = "abcdef";
string t = s.substr(2,3);

cout << t
```

```c=
執行結果為：cde
(從第二個字'c'，取3個字"cde")
```
### 5.找尋有沒有這東西/位置 (s.find)
```c=
s.find("abc");
```
* 如果**含有** "abc" :
```c=
string s = "sssabc";
cout << s.find(abc);
```
```c=
執行結果 : 3
//因為"abc"在 s = "sssabc"; 的第a[3]格
```
* 如果**沒有含有**"abc" :
```c=
string s = "ssssss";
cout << s.find(abc);
```
```c=
    執行結果 : 18446744073709551615
    //為亂數，實際上是 string::npos
```


---

## 二、字元 判斷 (char c)
都以`char c;` 舉例
### 1.基礎
* 首先必須要了解<font color="blue">每一個字元在電腦都有自己的代碼</font>
![IMG_4016](https://hackmd.io/_uploads/SyX4pD6fWx.jpg)
* 輸入`'0'`他的代碼是`48`
* 依此類推`'1'`代碼是`49`，`'2'`代碼是`50`。
會有連續性`A B C`和`a b c`也是一樣

<font color="blue">注意 ! 大小寫要分開計算，代碼是不一樣的</font>

<font color="AC19C9">[例題]</font>
```
輸入一個字串
輸出字串中所有的數字
例如輸入5ab9cd168eqq4qq
則輸出591684
```
既然是數字，那麼它的代碼應該會介於'0'到'9'之間
```c=
string s;
cin >> s;
for(int i=0;i<s.size();i++){
    if(s[i]<='9' && s[i]>='0') cout<<s[i];
}
```
<font color="AC19C9">[例題2]</font>
```
呈上題
找到字串中的所有數字後，把他們加起來
例如 : 5+9+1+6+8+4 = 33
```
先想想看現在他們是字元狀態的`'5'`和`'9'`，<font color="AC19C9">他們相加會變成`'59'`，而不是`5 + 9 = 14`</font>。
 ! 因此要把字元轉換成數字 ! 
 <font color="E68C27">**數字就減`'0'`，大寫英文就減`'A'`，小寫減`'a'`**</font>
 像是 :`'1'-'0' = 1` `'5'-'0' = 5`，再相加就可以了。


### 2.判斷一個字元 (用函數)
#### (1).是否是數字 在'0'~'9'內
```c=
char c;
cout << isdight(c);
```
#### (2).是否是字母 (大小寫都算) 在'A'~'Z' 和 'a'~'z'內
```c=
char c;
cout << isalpha(c);
```
* 兩者回傳均<font color="blue"> 1 表示是 、 0 表示否</font>
#### (3).判斷字母是小寫 ?  在'a'~'z'間
```c=
cout << islower('a');
```
#### (4).判斷字母是大寫 ?  在'A'~'Z'間
```c=
cout << isupper('A');
```
* 兩者回傳均<font color="blue"> 1 表示是 、 0 表示否</font>

### <font color="1d206e">**3.轉換字母大小寫**</font>
```c=
char c1 = 'A';
char c2 = 'b';

cout << tolwer(c1) << endl;    //大寫轉小寫
cout << toupper(c2) << endl;    //小寫轉大寫
```
```c=
輸出 :
a
B
```
> <font color="1d206e">常用在「忽略大小寫比較」的題目中</font>

## 四、陣列 判斷
### <font color="1d206e">1.一般陣列 vs vector</font>


| 比較項目             | 一般陣列    | vector                  |
| -------------------- | ----------- | ----------------------- |
| 宣告                 | int a[5]    | vector<int> a           |
| 大小是否可變         | X           | ✓ 可動態增加            |
| 是否能在執行中改大小 | X           | ✓ push_back()           |
| 取元素方式           | a[i]        | a[i]                    |
| 是否自動記錄長度     | X           | ✓ a.size()              |
| 安全取值             | X           | ✓ a.at(i)               |
| 排序                 | sort(a,a+5) | sort(a.begin(),a.end()) |
    
 <font color="1d206e">總而言之 vector 對比一般陣列，較為安全、方便 </font>

### 2.給陣列初始值
#### (1).一維陣列 : 
* 一般陣列只能在定義時初始化 (給予數值) :
```c=
int a[3] = {1,2,3};
```
* vector 可以在其他時間給予數值 :
        
```c=
vector<int> a(3);
a = {1,2,3};
```
#### (2).二維陣列也是一樣 :
```c=
int a[2][3] = {1,2,3,4,5,6};
```

```c=
vector<vector<int>> a(2,vector<int>(3));
a = {{1,2,3}{4,5,6}};
```
### 3. 初始值設0和最大值
#### (1).30 未完待續
#### (2).31 未完待續   
### 4.將陣列排序 (由小排到大) `sort`
* 一般陣列跟 vector 用法不一樣
```c=
int a[5];
sort(a,a+5);    
```
```c=
vector<int> a;
sort(a.begin(),a.end())
```
### <font color="1d206e">5.陣列的大小</font>
*    <font color="red"> 只有 vector 可以用</font>
```c=
vector<int> a;
cout << a.size();
```
### <font color="1d206e">6.翻轉的陣列</font>
```c=
vector<int> a = {1,2,3};
reverse(a.begin(),a.end());

for(int i = 0;i < 3;i ++){
     cout << a[i] << " ";                    
}
```

```c=
輸出 :
3 2 1
```
                     
# 叁、常用函數
### 1.取大值、取小值 (max、min)
比較兩個值留最大或最小的值
```c=
int x = 3,y = 4;
int z = max(x,y);
int z2 = min(x,y);                     
cout << z < " " < z2;                     
```           
```c=
輸出 : 
4 3    //3跟4比保留較大的4，保留較小的3;
```                     
### 2.數出現次數 (count)
數陣列某一範圍中 x 值的出現次數
```c=
vector<int> a = {1,2,2,2,3};
cout << count(a.begin(),a.end(),2);
```
```c=
輸出 :
3    //共有3個2
```
### 3.找第一個出現位置 (find)
找到 x 值在陣列某一範圍中的位置
 
```c=
vector<int> a = {4,6,8};
auto it = find(a.begin(),a.end(),6);

cout << "位置 : " << it - a.begin();
//it是位置訊息所以要減初始位置
```
```c=
位置 : 1    //位置在a[1]
```
### 4.交換 (swap)
交換兩個變數的值
```c=
int a = 5,b = 7;
swap(a,b);
cout << a << " " << b;
```
```c=
輸出 :
7 5 
```
* 原本做法
```c=
int a = 5,b = 7;
int x = a;
a = b;
b = x;
cout << a << " " << b;
//不可直接 a = b; 等號為把右邊的值往左邊丟。
```
```c=
輸出 :
7 5
```
### <font color="1d206e">5.二分搜尋 (binary_search)</font>
<font color="red">注意 ! 要先用`sort`排序完才能用二分搜尋法</font> 
    
```
未完待續
```
### 6.數學
#### (1).四捨五入
```c=
double x = 3.6;
cout << round(x);    //4
```


| 數值       | 結果 |
| ---------- | ---- |
|  round(3.4)          |  3    |
|  round(3.5)          |   4   |
| round(-3.5) |  -4   |

#### (2).無條件進位 (ceil,天花板)
```c=
cout << ceil(3.1)    //4
cout << ceil(-3.1)    //-3
```
#### (3).無條件捨去
*    其實變成`int`就好了
```c=
double a = 3.14;
int b = a;
cout << b;    //3
```
> 因`int`存放"整數"，所以會自動去掉
#### (4).絕對值
```c=
cout << abs(1-3);    //2
```
#### (5).平方次方 (pow)
```c=
int a = 5;

cout << pow(a, 2) << endl;  // 5² = 25
cout << pow(a, 3) << endl;  // 5³ = 125
```
#### (6).開根號 (sqrt)
```c=
int x = 16;

cout << sqrt(x) << endl;  // √16 = 4
```
#### (7).數字轉字串 (to_string)
未完待續
