Edited by 廖竑羿
## [#題目練習清單連結#](https://hackmd.io/ehioLPE5RviiBBjo1Cca3A?view)
## 基礎架構及輸出輸入
```cpp=
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int main(){
//你的程式寫在這裡 (這行不要寫!)
}
```
- #include<欲引用之標頭檔>
引用標頭檔
- using namespace std;
使用命名空間 std
- int main(){ //你的程式 }
你的主程式寫於大括號內
- ==;==
c++中的句號,每行程式最後記得要加 !
### 輸出
### 讓程式輸出一串文字
```cpp=
#include<iostream>
using namespace std;
int main(){
cout<<"Goodmorning!";
}
```
==cout<<== 為輸出函式
雙引號 " " 包住的內容稱為 ==string(字串)==
### 換行( endl 、 \n )
```cpp=
cout<<"Goodmorning!\n";
cout<<"Goodnight!"<<endl;
```
==\n== 及 ==endl== 皆為換行
若想輸出以下文字:
A : Hi, how are you ?
B : Fine !
程式碼->
```cpp=
cout<<"A : Hi, how are you ?"<<endl;
cout<<"B : Fine !"<<endl;
```
### 變數與資料型態
```cpp=
#include<iostream>
using namespace std;
int main(){
int x=3;
string s="abcde";
cout<<x<<endl;
cout<<s<<endl;
}
```
### 變數
像數學中的 x,y,z ,可以被帶入不同的數值
而變數就像一個容器,可以儲存各種不同的資料
不同種類的變數能處存不同種類的資料
上方程式碼中的 x,s 就是不同型態的變數
### 宣告變數
若要在程式中使用一個變數,需要讓電腦先知道他
使用變數之前,必須先新增、讓電腦知道這個變數
而這個動作稱為==宣告(declear)==
命名:英文、數字、符號
```cpp=
int x=6789;
float temperture=2.234;
string s1="abc",s2="cde";
char ch_student='j';
long long m;
```
### 全域變數、區域變數
==區域變數==是在函式、程式區塊中({})的變數。
只在宣告它們的區域內可以使用
==全域變數==是在函式外部宣告的變數
在宣告後的所有城市區塊都可使用
```cpp=
#include <iostream>
using namespace std;
int global = 100; // 全域變數
int main()
{
int y = 10; // y是區域變數
cout << globalVar << endl; // 可以在main函式內使用全域變數
return 0;
}
```
### 資料型態

! 常用 !
==int== , ==float== , ==string== (使用""夾著資料), ==char==(使用''夾住資料)
### 輸入
```cpp=
string s; //宣告變數
cin>>s; //輸入
cout<<s<<endl; //輸出
```
前面已經知道了如何將資料輸出
cin>>變數==為輸入函式
cin>>箭頭方向與cout<<相反
讓使用者輸入資訊
使得程式可以與人互動->
```cpp=
string s;
cout<<"What's your name ?"<<endl;
cout<<"Please enter your name."<<endl;
cin>>s;
cout<<"Good morning, "<<s<<endl;
```
連續輸入
```cpp=
string s,j,k;
cin>>s>>j>>k;
```
### 小練習
- [d483. hello, world](https://zerojudge.tw/ShowProblem?problemid=d483)
- [a001. 哈囉](https://zerojudge.tw/ShowProblem?problemid=a001)
## 運算
### 使用變數做運算
若在程式中宣告過的變數
則可以互相做運算,如加減乘除等
```cpp=
int a,b;
cin>>a>>b;
cout<<a+b<<endl;
cout<<a*b<<endl;
```
### 指派( assign )=
若想讓你的變數儲存某一特定資料
或者做一些運算
可以使用等號 = 將左方變數之資料改為右方資料
```cpp=
int a=3,b=5;
a=a+3; //a=6
a=a+b; //a=11
a=b; //a=5
a+=1; //a=6
a++; //a=7
```
### 運算符號
加號 ==+== :和數學的加號相同
減號 ==-== :和數學的減號相同
乘號 ==*== :和數學的乘號相同
除號 ==/== :如果是整數除法,就只留下商;
如果是小數除法,則是保留一些位數的小數,例如:
5 / 2 結果會是2
5.0 / 2.0 結果會是2.5
模(mod)==%==:除法取餘數,例如:
5 % 2 結果會是1
10 % 5 結果會是0
7 % 4 結果會是3
括號():和數學的括號相同,括號內的部分優先算。
如果要用括號包括號的話,同樣也是用這種小括號,例如((1+2)*(3+4))*5
### 常用數學函式
abs(x) -> 回傳 x 的絕對值
sqrt(x) -> 回傳 x 的平方根
pow(x,a) -> 回傳 x 的 a 次方
### 小練習
- 小明有n個1元硬幣,請問可以換成幾個10元硬幣? 剩下幾個1元硬幣?
請設計一個程式讓使用者輸入n,並輸出正確答案
- 小明到美國玩,發現溫度計顯示的是華氏溫度。請問華氏的x度是攝氏的幾度?
請設計一個程式讓使用者輸入華氏溫度,並輸出攝氏溫度
- 請設計一個程式讓使用者輸入四位數字,並依序輸出其千位、百位、十位、個位數字。
例如:輸入2345,則應該輸出 2 3 4 5
- 甲有n支鉛筆,乙的鉛筆是甲的2倍再多3支,丙的鉛筆是乙的3倍再少1支,丁的鉛筆比丙還要少5支,請問甲乙丙丁總共有幾支?
請設計一個程式讓使用者輸入n ,並輸出正確答案
## 條件判斷
### if else
基礎要素:
if(==要判斷的條件==){
若符合條件將會執行的動作
}else{
若沒有符合if的條件
程式將執行這裡
}
```cpp=
int a;
cin>>a;
if(a>10) cout<<a<<'>'<<10<<'\n';
else cout<<a<<"<="<<10<<'\n';
```
:::info
若 if , while , for 的 { } 中只有一行,則可省略
:::
### 判斷式
用於判斷兩者之關係

:::success
同時判斷多個條件
&& (and) 所有條件符合才會成立
|| (or) 符合其中一條件成立
:::

### 多個不相關if
```cpp=
if(a>0) {
cout<<"a>0"<<'\n';
}
if(a==10) {
cout<<"a==10"<<'\n';
}
if(a%2==0) {
cout<<"a%2==0";
}
else {
cout<<"!!!"<<'\n';
}
```
若有多個條件需要判斷,可以寫不只一個 if
### if 中的 if
```cpp=
int a;
cin>>a;
if(a>0) {
if(a>50) cout<<"big"<<'\n';
else cout<<"dog"<<'\n';
}else{
if(a%2==0) cout<<"cat"<<'\n';
else cout<<"spiderman"<<'\n';
}
```
輸入 37 , -9 , 240 分別會輸出什麼?
### else if
從最上方的 if 開始走
若沒有符合條件就繼續往下判斷
最後一定會執行某一段程式
```cpp=
char c;
cin>>c;
if(c=='A'){
cout<<"Good"<<'\n';
}
else if(c=='B'){
cout<<"ok"<<'\n';
}
else if(c=='C') {
cout<<"bad"<<'\n';
}
else {
cout<<"?????"<<'\n';
}
```
### 小練習
- [d063. 0 與 1](https://zerojudge.tw/ShowProblem?problemid=d063)
- [d064. ㄑㄧˊ 數?](https://zerojudge.tw/ShowProblem?problemid=d064)
- [a003. 兩光法師占卜術](https://zerojudge.tw/ShowProblem?problemid=a003)
- [d058. BASIC 的 SGN 函數](https://zerojudge.tw/ShowProblem?problemid=d058)
- [d060: 還要等多久啊?](https://zerojudge.tw/ShowProblem?problemid=d060)
## 迴圈 for , while
### while ( )
- 不知道要執行幾次
- 小括弧中的判斷式成立則執行{}
- 每次執行完重新判斷()中判別式
```cpp=
int i=2,b;
cin>>b;
while(i<b){
cout<<i<<' ';
i++;
}
while(b--){
cout<<"hi ";
}
```
==小心無窮迴圈==
```cpp=
int i=2;
while(i>0){
cout<<i<<' ';
i++;
}
```
### for ( )
- 知道要執行幾次
- 重複執行{}內程式,直到次數達標
- Ex:輸出1000次“嗨”、計算6的13次方........
寫法:
for迴圈中需要計算「迴圈執行幾次了」
所以需要另外使用一個變數來作為「計數器」
通常將這個變數的名稱取為 i 或 j 或 k
使用這個變數時有三項重點
1. 設定初始值
2. 設一個檢查條件,每執行一次迴圈就檢查它是否還符合條件(還符合才能繼續跑迴圈)
3. 每執行一次迴圈將變數做變動 Ex:i++, i+=2 , i*=2 ............
:::info
for 中可搭配 for ,if , while ................
:::
- Ex:
```cpp=
int a,b;
cin>>a>>b;
for(int i=0;i<10;i++){ //輸出十次12345
cout<<"12345"<<'\n';
}
for(int i=0;i<a;i++){ //輸出[0,a]中之每個偶數
if(i%2==0) cout<<i<<' ';
}
for(int i=a;i<=b;i+=2){ //輸出a,a+2,a+4......直到 i > b
cout<<i<<' ';
}
for(int i=0;i<a;i++){ //輸出a*b的長方形
for(int j=0;j<b;j++) {
cout<<'*';
}
cout<<'\n';
}
```
### break , continue
若在迴圈中執行 break ,則直接離開迴圈
若在迴圈中執行 continue ,則直接進入下一次迴圈
Ex:輸出第一個的大於 a 又可被 7 整除的整數
```cpp=
for(int i=a;i<1000;i++) {
if(i%7==0){
cout<<i<<'\n';
break;
}
}
```
Ex:輸出 a 到 b 中不被 3 整除的整數
```cpp=
for(int i=a;i<=b;i++) {
if(i%3==0) continue;
cout<<i<<' ';
}
```
### 小練習
- [c418. Bert的三角形 (1)](https://zerojudge.tw/ShowProblem?problemid=c418)
- [c419. Bert的三角形 (2)](https://zerojudge.tw/ShowProblem?problemid=c419)
- [c420. Bert的三角形 (3)](https://zerojudge.tw/ShowProblem?problemid=c420)
- [a147. Print it all](https://zerojudge.tw/ShowProblem?problemid=a147)
- [a005. Eva 的回家作業](https://zerojudge.tw/ShowProblem?problemid=a005)
## 陣列
### 陣列
使用變數時我們會宣告 a,b,c,d......
若需要使用到1000000個變數呢?
```cpp=
int arr[1000000]; //宣告
arr[3]+=3; //對特定位置操作
arr[7]=7890; //將特定位置指派成某資料
```
陣列為一列變數,大小為1000000的整數陣列相當於1000000個一排的整數變數
可以對每個特定位置做不同的操作
```cpp=
#include <iostream>
using namespace std;
int arr[100005]; //宣告在這
int main(){
int k;
}
```
宣告時將陣列宣告在全域變數,較不容易發生stackoverflow(溢位)
:::danger
c++中,位置編號(索引)是從 0 開始 !
若有a[100]有100個可以儲存變數的盒子
編號是 0 - 99 , 不是 1 - 100
:::
### 輸出輸入
```cpp=
int arr[1005];
cin>>n;
for(int i=0;i<n;i++) cin>>arr[i];
for(int i=0;i<n;i++) cout<<arr[i];
```
常見 errors
```cpp=
int arr[5];
cin>>arr[5]; // arr[0] - arr[4]
cout<<arr[-1]; //編號為負
```
### 多維陣列
若將陣列想像成一排儲存資料的變數
二維陣列就是很多排陣列組成的矩形

a [ i ] [ j ] 表示 a 陣列第 i 行 (row) 第 j 列 (column)
可搭配迴圈輸入或輸出/操作
```cpp=
//輸入一 n*m 陣列
int n,m;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>arr[i][j];
}
}
```
### 小練習
- [f345. 新手練習題—陣列](https://zerojudge.tw/ShowProblem?problemid=f345)
- [g595. 1. 修補圍籬](https://zerojudge.tw/ShowProblem?problemid=g595)
- [d587. 參貳壹真好吃](https://zerojudge.tw/ShowProblem?problemid=d587)
- [i791. pA. 沒有人受傷的世界完成了](https://zerojudge.tw/ShowProblem?problemid=i791)
## 字串
### 常見操作
- ==+== 相加
- s[id]存取特定位置
- size(),length()表示字串長度
- 遍歷
- 子字串
- 整數、字串轉換
ex:
```cpp=
int main(){
string s1="abcdefg";
string s2="1234567";
// + 相加兩字串
string s3=s1+s2;
// s [index] 存取特定位置字元
cout<<s1[0]<<'\n';
cout<<s1[1]<<'\n';
//s.size() , s.length() 表示長度
cout<<s1.size()<<'\n';
cout<<s2.length()<<'\n';
//遍歷 s 字串中每個字元
for(auto c:s1){
cout<<c<<'\n';
}
//子字串 (起始index,結束index)
cout<<s1.substr(1,4)<<'\n';
cout<<s2.substr(0,5)<<'\n';
//字串、整數轉換
string s = to_string(12345); //將整數儲存成字串
int number = stoi("567898"); //將字串儲存成整數
}
```
### Ascii code

應用:
```cpp=
int main(){
cout<<char(97)<<'\n'; // a
cout<<'G'-'A'<<'\n'; // 6
cout<<'8'-'0'<<'\n'; // 8
}
```
### 小練習
- [a022. 迴文](https://zerojudge.tw/ShowProblem?problemid=a022)
- [a130. 12015 - Google is Feeling Lucky](https://zerojudge.tw/ShowProblem?problemid=a130)
- [b428. 凱薩加密](https://zerojudge.tw/ShowProblem?problemid=b428)
- [d235. 10929 - You can say 11](https://zerojudge.tw/ShowProblem?problemid=d235)
## 函數及遞迴
### 常用內建函數
```cpp=
string ss;
getline(cin,ss); //將輸入的整串字包含空格存在ss內
int x = abs(a); //回傳 a 的絕對值
int y = pow(a,n); //回傳 a 的 n 次方
int z = sqrt(a); //回傳 a 的平方根
int m = max(x,y) //回傳 a,b 中較大值
int n = min(x,y) //回傳 a,b 中較小值
sort(arr,arr+n); //將 arr[0] - arr[n-1] 由小而大排序
sort(arr,arr+n,greater<int>()); //同上,由大而小
memset(arr,0,sizeof(arr)); //將 arr 中每個元素設定為 0 (只能為 0,-1)
//針對已經排序(由小而大)之陣列
auto it = lower_bound(arr,arr+n,k); //回傳arr中 >= k的最小值的位置
auto IT = upper_bound(arr,arr+n,k); //回傳arr中 > k的最小值的位置
```
### 標頭檔
:::info
可引用包含所有標頭檔的標頭檔#include<bits/stdc++.h>
:::
若沒有( mac 某些版本貌似沒有 )
大部分函式會在以下幾個函式庫內(見最後方)
想知道哪個函式屬於哪個函式庫可再上網查詢
```cpp=
#include <iostream>
#include <queue>
#include <vector>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <string.h>
#include <utility>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <ctime>
```
### 自訂函數
若想使用一個函數,但沒有內建函數可以使用
這時候我們可以自行宣告一個函數
基本結構:
返回值類型 函數名稱(參數列表)
{
// 函數的程式碼塊
// 可以包含多條語句
// 可以使用參數進行計算
// 可以使用 return 陳述式返回值(如果需要)
}
ex:
```cpp=
#include <iostream>
using namespace std;
int sum(int a, int b) //return int
{
int result = a + b;
return result; // 返回兩個數字的和
}
void print(){ //無回傳值
cout<<"hi"<<'\n';
}
int main()
{
int x = 5;
int y = 3;
int z = sum(x, y); // 呼叫函數sum並將返回值存儲在變數z中
cout << "Sum: " << z << endl;
print();
return 0;
}
```
### 遞迴
==遞迴==(Recursion)是一種在程式中使用函數呼叫自我技巧
常用於解決需要重複執行相同或相似任務的問題
```cpp=
int factorial(int n){
// 當 n 為 0 或 1 時,階乘為 1
if (n == 0 || n == 1){
return 1;
}
// 遞迴情況:計算 n 的階乘
else{
return n * factorial(n - 1);
}
}
```
### 小練習
- [c002. 10696 - f91](https://zerojudge.tw/ShowProblem?problemid=c002)
- [c813. 11332 - Summing Digits](https://zerojudge.tw/ShowProblem?problemid=c813)
## 結構 (struct)
自行定義一種結構,使得可以儲存不同類型的資料
```cpp=
#include <iostream>
#include <string>
using namespace std;
// 定義一個結構
struct Person {
string name;
int age;
char gender;
};
int main() {
// 創建一個 Person 類型的變數
Person person1;
person1.name = "Alice";
person1.age = 30;
person1.gender = 'F';
// 創建另一個 Person 類型的變數
Person person2;
person2.name = "Bob";
person2.age = 25;
person2.gender = 'M';
// 輸出 person1 的資訊
cout << "Person 1: " << person1.name << ", " << person1.age << " years old, Gender: " << person1.gender << endl;
// 輸出 person2 的資訊
cout << "Person 2: " << person2.name << ", " << person2.age << " years old, Gender: " << person2.gender << endl;
return 0;
}
```
### 小練習
- [d091. 00476 - Points in Figures: Rectangles](https://zerojudge.tw/ShowProblem?problemid=d091)
## 指標 (pointer)