{%hackmd @hipp0\Hippotumuxthem %}
<style>
.text-center{
text-align: center; //文字置中
}
.text-left{
text-align: left; //文字靠左
}
.text-right{
text-align: right; //文字靠右
}
</style>
<style>
.reveal .slides {
text-align: left;
font-size:30px;
}
</style>
# C++ 基礎I
---
## 編譯器選擇
- C++ online GDB
- repl.it
- else (VScode)
---
<h2 style='color:#C4C400'> 一個完整的程式碼 </h2>

----
<h2 style='color:#C4C400'> 一個完整的程式碼 </h2>
- 標頭檔
- 主函式
- 記得每一段後面記得要分號 ;
----
<h2 style='color:#C4C400'> using namespace std </h2>

---
<h2 style='color:#C4C400'> 變數的宣告與指派</h2>
----
### 變數宣告:
```cpp=
int a = 100;
long long b = 200000000000;
char c = 'a';
double d = 2.564;
string e = "ABC";
bool ck = 0; //false
```
----
## 常見資料型態:
----
### int:
- 整數型態
- 4Byte 可以存放 -2^31 ~ 2^31-1
- 超過會出現無法預期的結果
- 量級$10^9$
----
### long long:
- 長整數型態
- 8Byte 可以存放 -2^63 ~ 2^63-1
- 運算速度小於int
- 量級$10^{18}$
- 記得要看清楚題目資料範圍!
----
### double:
- double:
- 雙倍精確度浮點數
- double的精度為15~16位
- 會有誤差
- 不使用float
- 題目很少有浮點數運算
----
### char:
- 字元型態
- 字元以兩個單冒號括住,像是’a’
- 可以用int型態表示,為ASCII碼,例如’a’ = 97
----
### string:
- 字串型態
- 很多個字元串在一起,以雙冒號括住,例如 “I am Hippo”
- 和char[]語法不太一樣,不過string方便很多。
----
### bool:
- 布林型態
- 僅表示 true(1) 和 false(0)
- 常用來判斷某些情況是否用過了。
----
### 不常用和注意事項:
- float因為準確度太低,誤差太大,不適合在寫題目使用。
- 需要一開始就定義變數的型態,才能給值。
- 若宣告時未指派值,變數的值不一定是 0,可能是任何數。
----
### 指派
在程式語言的世界中 = 這個符號有著不同的意思。
它代表著的,並非我們日常生活中的等於,而是指派。
----
所以,如果我們寫下列的程式碼,意思為 a定義為整數型態,並且給他一個值為3
```cpp=
int a;
a = 3; // a你現在被我指派為3了!!
```
----
同樣的,以下的程式碼也是合法的,和我們理解的 = 不同,現實中的相等是用==表示
```cpp=
int a = 1234;
a = 1986;
a = 4060;
```
----
逼瘋數學人
```cpp=
int a = 3;
a = a + 1; // ?????
```
----
### 型態互轉
某些型態是可以互相轉換的,例如
```cpp=
int a = 3;
long long b = 5;
double c = 7.321;
a = c;
b = c;
c = a;
```
不過要注意的是,當浮點數轉為int時候,小數點會全部捨去。
---
<h2 style='color:#C4C400'> 輸入輸出 </h2>
----
### 輸入cin
```cpp=
int x;
cin >> x;
```
那如果我輸入123abc,x會存放什麼,答案是123
cin一個整數時,程式會一直讀取直到下一個位置的字元不是數字為止!
----
### 多輸入
假設我們想輸入 1 2 3 4 5 每個都用空格隔開
```cpp=
int a, b, c, d, e;
cin >> a >> b >> c >> d >> e;
```
----
### 輸出cout
運作(輸出的東西,若為文字,用 “” 包起來)
```cpp=
int x;
cin >> x;
cout << " x值為 : " << x << endl;
```
題目正常行尾要輸出換行字元 ’\n’ 或者打 endl 來換行
$務必注意cin,cout 的箭頭方向$
----
## 四則運算
```cpp=
#include <bits/stdc++.h>
using namespace std;
int main(void){
int a ,b;
cin >> a >> b;
cout << "加法:" << a + b << '\n';
cout << "減法:" << a - b << '\n';
cout << "乘法:" << a * b << '\n';
cout << "除法:" << a / b << '\n';
cout << "取餘:" << a % b << '\n';
}
```
----
### 常用
- $+$ 加法
- $-$ 減法
- $*$ 乘法
- $/$ 除法
- % 取餘數
----
### 運算後指派
```cpp=
a += 5; // a = a + 5
b -= 2; // b = b - 2
c *= 3; // c = c * 3
d /= 4; // d = d / 4
a += b; // a = a + b
```
----
### 針對 a = a + 1 , a = a - 1 ,有下列寫法
```cpp=
int a = 1;
++a; // a = a + 1
--a; // a = a - 1
a++; // a = a + 1
a--; // a = a - 1
```
----
### 不同之處
- a++ 會做完事情在+1,++a會先+1在做事情
```cpp=
int main() {
int A = 2;
int B = 2;
int C = A++;
int D = ++B;
cout << "C = " << C << ",D = " << D << '\n';
return 0;
}
```
---
<h2 style='color:#C4C400'> 條件判斷與基礎邏輯 </h2>
----
### 格式
```cpp=
if (條件) {
做事情;
}else if(條件){
做事情;
}else if(條件){//可以做很多次else if
做事情;
}else{
做事情;
}
```
----
### 舉個例子
```cpp=
#include <iostream>
using namespace std;
int main(void){
int a, b;
cin >> a >> b;
if(a > b){
cout << "a比較大" << '\n';
}else if(a < b){
cout << "b比較大" << '\n';
}else{
cout << "ab一樣大" << '\n';
}
}
```
----
### 注意事項
特別需要注意的有以下幾點:
- 條件由小括弧包含住
- 滿足條件後要做的事情由大括號包含住
- 若滿足條件後要做的事情只有一句(以分號為界),可不包大括弧
- if 可單獨存在,也就是說,就算沒有後面的 else if 跟 else ,也是合法的
- if 可多層套疊
----
### 基礎邏輯
| 基礎邏輯 | 意思 | 例子 |
| -------- | -------- | -------- |
| > | 大於 | a > 3 |
| < | 小於 | a < 3 |
| == | 等於 | a == 3 |
| != | 不等於 | a != 3 |
| >= | 大於等於 | a >= 3 |
| <= | 小於等於 | a <= 3 |
----
| 基礎邏輯 | 意思 | 例子 |
| -------- | -------- | -------- |
| && | 且 | a > 3 && a != 5 |
| \|\| | 或 | a > 3 \|\| a == 0 |
| ! | 否 | !(a>3) |
----
### 注意事項
- 特別注意 並沒有 3 < a < 5 這種寫法,需要用 3 < a && a < 5 才行,危險的地方是,這個程式碼並不會導致編譯錯誤
- 多個判斷有前後順序,由前往後,在陣列中很常用來判斷邊界問題。
- 記住!! 等於是 == 而且寫成a=3編譯也不會出錯,然後debug半天才看到,會很想罵髒話
----
## 練習
A001 A002 A003
網址:[ncuma-oj.math.ncu.edu.tw](https://ncuma-oj.math.ncu.edu.tw)
----
### 三元運算子
什麼是三元運算子(ternary operator),簡單說它是 if … else … 的精簡版。
```cpp=
條件式 ? 條件式為true時執行的陳述句 : 條件式為false時執行的陳述句
```
----
上面語法看不懂也沒關係
一般寫 if … else … 的例子如下:
```cpp=
int ret, a = 10, b = 11;
bool state = true;
if (state)
ret = a;
else
ret = b;
cout << ret << '\n';
```
----
用三元運算子可以寫成
```cpp=
條件式 ? 條件式為true時執行的陳述句 : 條件式為false時執行的陳述句
```
```cpp=
int ret, a = 10, b = 11;
bool state = true;
ret = state ? a : b;
cout << ret << '\n';
```
---
<h2 style='color:#C4C400'> 進階運算 </h2>
----
### 浮點數誤差
- 因為電腦是離散的結構,所以在使用double進行加加減減多少會產生一些誤差。
- 此時我們就不以==來判斷是否相等,取而代之的是,我們只需判斷他們之間差的絕對值是否小於特定值,我們稱這個值為epsilon。
----
另外,在程式中可以使用1e5,1e6…這種用法,簡單說就是10的X次方,所以我們在定義epsilon可以不用定義的那麼長。
例如double eps = 0.000000001;
等價於 eps = 1e-9;
```cpp=
double a, b;
double eps = 1e-9;
cin >> a >> b >> c;
if(a > b && a-b < eps) cout << "Equal" << '\n';
else if(a < b && b-a < eps) cout << "Equal" << '\n';
else cout << "not Equal" << '\n';
```
----
### 字元運算
- 在提到char字元的時候,有說到每個字元會對應到一個[ASCII碼 - 詳情點進去看](http://kevin.hwai.edu.tw/~kevin/material/JAVA/Sample2016/ASCII.htm)
- 所以字元在進行運算的時候,會將其視為ASCII碼! 例如 'a'+10 其實就是 97+10 對應過去的字元也就是'k';
- 請注意 A’~’Z’以及’a’~’z’以及’0’~’9’,在ASCII table的位置是連續的,但這三者之間並非連續的,'A' 是 65 , 'a' 是 97 , '0' 是48
----
### <a style = "color:purple"> "大寫轉小寫" </a>
- 因為’a’ 和 ‘A’ 差距是 97-65 = 32 ; 不知道也沒關係可以利用型態互轉來計算
- 我們只要大寫字母 + 差距 就會是小寫, 反之就減回去。
```cpp=
char c;
cin >> c;
c += 'a' - 'A'; // c = c + ('a' - 'A');
cout << c ;
```
----
### 字元比較
- 字元的比較以ASCII碼來比。 例如 ‘a’ > ‘A’ , ‘A’ > ‘0’
- 也可以拿來判斷位元是否在裡面,像是判斷字元是不是小寫
```cpp=
char c;
cin >> c;
if(c >= 'a' && c <= 'z') cout << "c 是小寫" << '\n';
else cout << "C 不是小寫" << '\n';
```
----
### 位元運算
電腦以二進位 0 和 1 儲存,有以下幾種位元運算
| | 意思 | 例如 |
|:--------:|:--------------------------------- |:----------------------:|
| & | 且(and),同1為1,其餘為0 | 100 & 101 = 100 |
| \| | 或(or),其1為1,其餘為0 | 100 \| 101 = 101 |
| ^ | 互斥(xor),其1為1,同1為0,同0為0 | 100 ^ 101 = 001 |
| ~ | 非(not),把1換0,把0換1 | ~ 100 = 011 |
----
### 左右移
| | 意思 | 例如 |
|:--------:|:--------------------------------- |:----------------------:|
| << | 左移(將一個變數向左移動並且補0) | 101 << 1 = 1010 |
| >> | 右移(將一個變數向右移動並且捨去) | 101 >> 1 = 10 |
----
### <a style = "color:purple"> "大寫轉小寫" </a>
如果利用xor的性質,是不是就剛好可以讓大小轉小寫,小寫轉大寫了呢?
```cpp=
char c;
cin >> c;
c = c ^ 32;
cout << c << '\n';
```
----
### <a style = "color:purple">"乘$2^n$" 除$2^n$</a>
- 利用二進位的特性,假設二進位數字1010 乘2的時候,會變成10100,是不是就剛好向左移動了一位。
- 反之就是除法,所以我們可以這樣寫
```cpp=
int a;
cin >> a;
cout << "a * 2 = " << (a << 1) << '\n';
cout << "a / 2 = " << (a >> 1) << '\n';
```
- 請注意,因為cout cin的箭頭和左移右移一樣,所以需要括起來,以免出錯。
----
### <a style = "color:purple"> "是否為奇數" </a>
我們在判斷一個數字是否為奇數很顯然會這樣寫
```cpp=
int a;
cin >> a;
if (a % 2 == 1) cout << "是奇數" << '\n';
else cout << "不是奇數" << '\n';
```
----
但我們可以利用 true 為 1, false 為 0 的特性,搭配 & 且 (and)。如果是奇數的話2進位的最右端一定是1,所以&1的結果就會是 1 (true)
```cpp=
int a;
cin >> a;
if (a&1) cout << "是奇數" << '\n';
else cout << "不是奇數" << '\n';
```
----
### 這樣有什麼好處? 感覺變得好難理解 ?
理由是使用後者的話可以加速約600%的效率 有興趣可以看這篇[利用位元運算加速運算效率](http://chuiwenchiu.wordpress.com/2007/05/11/as3)
---
<h2 style='color:#C4C400'> 迴圈 </h2>
----
當我們需要重複做同一件事很多次,總不能一個一個全部寫出來,如果要重複1000千次,那是不是程式碼就要幾千行,影響了可讀性,所以便會使用迴圈,而迴圈有下列的用法。
----
### for
最常用的迴圈,如下:
```cpp=
for (int i = 0 ; i < 100 ; i++){
cout << i << '\n' ; // do things
}
```
----
```cpp=
for ( 1 ; 2 ; 3 ){ do things }
```
for迴圈有四件事要做
1. 在第一個在分號前,代表程式執行到迴圈時,第一件會做的事情,像是我宣告了一個 i = 0
2. 在第二個分號前,代表程式進行的條件,如果不滿足,便會離開這個迴圈,像是範例中,只要 i < 100 就會繼續。
3. 執行for迴圈內文,像是我輸出 i 的值
4. 在第二個分號後,代表每次執行迴圈一次後,程式會做的事,像是我讓i的值+1
----
### string
記得要加標頭檔
```cpp=
#include <string>
```
----
### string 基本操作
字串長度 : 變數名稱.length()
```cpp=
string a;
cin >> a;
cout << a << "長度=" << a.length() << '\n';
```
----
### string 使用 for迴圈遍歷
在處理字串的時候很長需要一個一個字元來判斷,此時就會用到 length(),舉個簡單例子。
```cpp=
string a;
cin >> a;
for (int i = 0 ; i < a.length() ; i++) {
if (a[i] >= '0' && a[i] <= '9') cout << "number" << '\n';
else if (a[i] >= 'a' && a[i] <= 'z') cout << "小寫" << '\n';
else if (a[i] >= 'A' && a[i] <= 'Z') cout << "大寫" << '\n';
else cout << "其他" << '\n';
}
```
----
## 練習
A004 A005
網址:[ncuma-oj.math.ncu.edu.tw](https://ncuma-oj.math.ncu.edu.tw)
{"title":"C++基礎語法I","description":"C++基礎語法","contributors":"[{\"id\":\"b4bc52a4-04a8-4c6d-920a-32b9ab31a7f9\",\"add\":20390,\"del\":11494},{\"id\":\"d5b90de4-9b8e-4a36-a782-226db16cf725\",\"add\":1,\"del\":3}]"}