# C++學習筆記
:::info
**Zong Yan** & **You Jun**
:::
---
## :book:學習內容
### :small_blue_diamond: 基本輸入輸出、變數、資料類別
### :small_blue_diamond: if判斷、switch判斷
### :small_blue_diamond: for迴圈、一維陣列
### :small_blue_diamond: while迴圈、迴圈控制(contunu、break))
### :small_blue_diamond: 多維陣列、多重迴圈
### :small_blue_diamond: function函式
### :small_blue_diamond: 字串(string)、常用字串函數
### :small_blue_diamond: struct結構
### :small_blue_diamond: 遞迴
---
## :books:學習方式
```mermaid
graph LR
看資料做題目-->會;
看資料做題目-->不會;
會-->特殊;
會-->不特別-->有印象就好;
特殊-->解題報告
不會-->看看其他人的解題報告;
看看其他人的解題報告-->了解概念並自己做一次-->會;
```
---
## :speak_no_evil:基本輸入輸出、變數、資料型態
:::success
非常直觀
:::
### :computer:輸入/輸出
```c++=
#include <bits/stdc++.h> //標頭檔
using namespace std;
int main()
{
int n; //宣告整數n
cin>>n; //輸入n
cout<<n<<endl; //輸出
return 0; //記得不要消失就好
}
```
#### :nerd_face:
標頭檔
可以把它想成圖書館,每個書櫃都裝不同類型的書,當你要用書時,就會去那類的書櫃尋找,這時```include < >```就像去那個書櫃。\
標頭檔有超多種,我覺得很難記:relieved:有個很好用的東西```#include <bits/stdc++.h>```包括了所有標頭檔案,很好用:smirk:
### :desktop_computer: 資料類型
|表示方法|範圍|用途|
|:--:|:--:|:--:|
|int|-2,147,483,648 ~ 2,147,483,647|放整數|
|unsigned int|0 ~ 4,294,967,295|放整數|
|short|-32,768 ~ 32,767|放整數|
|long long|-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807|放整數|
|unsigned long long|0 ~ 18,446,744,073,709,551,615|放整數|
|char||放字元|
|float|10^-38^ ~ 10^38^|放浮點數(7位)|
|double|10^-308^ ~ 10^308^|放浮點數(15位)|
#### :nerd_face:
使用方式: 表示方法 資料名稱
***例*** : 宣告一個整數(<2147483647)
```int n;```
:grimacing:注意!!!避免溢位
[link:zerojudge c221](https://zerojudge.tw/ShowProblem?problemid=c221 "前往")
:::warning
駭客題:這題很酷
//奇妙的緣分遇到這題
```c++=
#include<bits/stdc++.h>
using namespace std;
int main(){
int a,b;
cin>>a>>b;
cout<<a+b<<'\n';
}
```
題目:請輸出一組合法的a,b,使上述程式輸出錯誤答案
可以看到範圍是int
只需要讓他超出範圍,a+b答案就錯了
```
#include<bits/stdc++.h>
using namespace std;
int main(){
cout<<2147483645<<" "<<5<<'\n';
}
```
原本我以為這題很簡單,結果一開始看到很錯愕
溢位(overflow) :+1:
:::
<br>
## :speak_no_evil:if判斷、switch判斷
:::success
~~能用if 我就不用switch~~,還有一個三元運算子
:::
### if語法
```c++=
#include <bits/stdc++.h>
using namespace std;
int main()
{
if(條件)
{
如果條件成立執行的動作
}
else
{
如果條件不成立執行的動作
}
return 0;
}
```
[link: zerojudge c461](https://zerojudge.tw/ShowProblem?problemid=c461 "前往")
:::warning
題目敘述去zerojudje看
有a,b兩數(0和1)
AND:使用```(a&b)```當兩數皆為1,結果為1,其餘為0
OR:使用```(a|b)```當兩數其一為1,結果為1,其餘為0
XOR:使用```(a^b)```當兩數不相同,結果為1,其餘為0
接下來就加上if判斷
!!!注意運算子優先順序
[參考連結](http://programingman.blogspot.com/2015/01/cc.html "前往")
```c++=
#include <bits/stdc++.h>
using namespace std;
int main()
{
int m,n;
bool a;
while(cin>>m>>n>>a)
{
bool f=0; //判斷是否有結果
if(m)m=1;
if(n)n=1;
if((m&n)==a)
{
cout<<"AND"<<"\n";
f=1; //有結果
}
if((m|n)==a)
{
cout<<"OR"<<"\n";
f=1;
}
if((m^n)==a)
{
cout<<"XOR"<<"\n";
f=1;
}
if(f==0) //沒有
cout<<"IMPOSSIBLE"<<"\n";
}
return 0;
}
```
:::
### switch語法
```c++=
#include <bits/stdc++.h>
using namespace std;
int main()
{
switch(要判斷的東西)
{
case 第一種結果:
執行的動作
break; //很重要
case 第二種結果:
執行的動作
break;
.
.
.
case 第n種結果:
執行的動作
break;
default: //結果都不成立
執行的動作
break;
}
return 0;
}
```
### 三元運算子(適當使用能省很多行)
```c++=
#include <bits/stdc++.h>
using namespace std;
int main()
{
cout<<(條件 ? 如果條件成立執行的動作 : 如果條件不成立執行的動作 );
return 0;
}
```
---
## :speak_no_evil:for迴圈、一維陣列
:::success
陣列的第一個位置是0!:no_mouth::no_mouth::no_mouth:
:::
### for迴圈語法
``` c++=
#include<bits/stdc++.h>
using namespace std;
int main()
{
for(初始值;條件;調整)
{
執行的動作;
}
return 0;
}
```
### 一維陣列
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | index(索引值) |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | 3 | 5 | 7 | 9 | 11 | 13 | 15 | 17 | value(存放的內容) |
```c++=
#include <bits/stdc++.h>
using namespace std;
int main()
{
宣告一維陣列
int a[5]; //初始值不確定,陣列大小為5
int b[5]={};
int c[5]={0}; //後面會全部填0
int d[5]={0,0,0,0,0} //初始值全部是零
int e[]={0,0,0,0,0} //陣列大小為5
return 0;
}
```
### :bookmark:
10~13簡單來說,只要有給初始值,後面沒給的全部自動填0
## :speak_no_evil:While迴圈,進階迴圈控制(continue,break)
:::success
while迴圈常用在不確定迴圈次數;for迴圈常用在已知迴圈次數
:::
### while語法(先判斷條件才執行動作)
``` c++=
#include <bits/stdc++.h>
using namespace std;
int main()
{
初始值
while(條件)
{
執行的動作;
調整;
}
return 0;
}
```
### do while語法(一定先執行一次動作再判斷條件)
``` c++=
#include <bits/stdc++.h>
using namespace std;
int main()
{
初始值
do
{
執行的動作;
調整;
}while(條件); //這裡要加分號
return 0;
}
```
### 進階迴圈控制(continue,break)
#### continue:如果條件成立,直接跳到下一次迴圈
#### break:如果條件成立,結束所在的迴圈
---
#### continue
``` c++=
#include <bits/stdc++.h>
using namespace std;
int main()
{
int sum=0;
for(int i=1;i<=10;i++)
{
if(i%2==0) //如果i是偶數,底下的動作不會執行,直接跳到下一次迴圈
{
continue;
}
sum+=i;
}
cout<<sum;
return 0;
}
```
#### break
``` c++=
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,sum=0;
while(cin>>n)
{
if(n==0)
{
break; //只要n=0,就結束迴圈
}
sum+=n;
}
cout<<sum;
return 0;
}
```
## :speak_no_evil:多維陣列、多重迴圈
:::success
這個東西很... :exploding_head: :exploding_head::exploding_head:
:::
### 多重迴圈
``` c++=
#include <bits/stdc++.h>
using namespace std;
int main()
{
for(int i=1;i<=9;i++) //外圈
{
for(int j=1;j<=9;j++) //內圈
cout<<i<<"*"<<j<<"="<<i*j<<endl; //外圈跑一次,內圈跑九次
}
return 0;
}
```
### 二維陣列(直行橫列) (i,j)
| (0,0) | (0,1) | (0,2) | (0,3) |
| ----- |:----- | ----- |:----- |
| (1,0) | (1,1) | (1,2) | (1,3) |
| (2,0) | (2,1) | (2,2) | (2,3) |
| (3,0) | (3,1) | (3,2) | (3,3) |
io加速
```c++=
std::ios::sync_with_stdio(false);
std::cin.tie(0);
```
## :speak_no_evil:function函式
:::success
重複使用
:::
### 語法
``` c++=
回傳值類型 函式名(輸入值類型 a,輸入值類型 b) //用,分隔
{
.
.
.
return 回傳值;
}
int sum(int a,int b)
{
return a+b; //回傳兩值相加
}
/*回傳值類型
void:無回傳值
auto:從return句推斷類型
*/
int main()
{
int a,b;
while(cin>>a>>b)
{
cout<<sum(a,b)<<"\n"; //呼叫sum函式
}
return 0;
}
```
## :speak_no_evil:字串(string)、常用字串函數
:::success
字元陣列,就是把很多字排成陣列
:::
### 語法
```c++=
宣告
string str1; //內容為空字串
string str2="XXX"; //字串是XXX
//上面={'X','X','x','\0'}後面會加一個空字元
讀入
string str1;
cin>>str1; //輸入I am back
cout<<str1; //顯示只有I,因為C++判定cin的時候,空白被當成定界符
getline(cin,str1); //可以讀入整行字串
cout<<str1;//顯示I am back
getline(cin,str1,'#'); //讀入整行字串,遇到#停止 輸入hey hey #ahh
cout<<str1; //輸出僅有hey hey,因為遇到#停止了
string s;
getline(cin, s, EOF); //全
字串可相加
string str1="C++";
string str2="is cool";
string str3=str1+str2; //C++is cool
可利用索引值找相對應的字元
str1="I like C++";
str1[0]='I'
str1[1]=空白
str1[2]='l'
遍歷字串每一個字元
string str1;
for(int i=0;i<str1.size();i++)
cout<<str1[i]<<"\n"
for(auto ch : str1) //auto自動判斷變數類型(C++11)
cout<<ch<<"\n"
```
---
### size(),length()取得字串長度,empty()判斷字串長度是否為零
```c++=
str1="I like C++";
str1.size()=10
str1.length()=10
str1="I like C++";
str2="";
str1.empty=0 //如果字串為空輸出1,不為空則輸出0
str2.empty=1
```
---
### substr利用索引值和指定長度尋找子字串,resize修改字串長度和內容
```c++=
substr(索引值,指定長度)
str1="I like C++";
cout<<str1.substr(2,4); //顯示like
resize(修改長度,新增字元)
str1="I like C++";
cout<<str1.resize(str1.size()+2,'-'); //顯示I like C++--
注意 string str2=str1.resize(8); //此行錯誤(resize沒有回傳值)
```
---
### strungstream字串流(型態的轉換)
``` c++=
string str;
stringstream ss;
cin>>str; //999
str+=1; //錯誤,string 不可直接加數字
int n; //如果str要輸入小數就用double
ss<<str; //str放入ss
ss>>n; //ss給n數字
n+=1;
cout<<n; //1000
string s="2 4 8";
stringstream ss(s); //
int a=0,b=0,c=0,d=0;
ss >> a; //第一個字轉成int給a
ss >> b; //第二個字轉成int給a
ss >> c;
ss >> d;
cout << a << " " << b << " " << c << " " << d << "\n"; //2 4 8 0 轉出的不會重複
cout <<ss.str(); //2 4 8 ss.str() 直接印出ss中的字串
string s=" 2 4 8"
stringstream ss(s);
string st="1";
ss << st; //ss 1 4 8 //2被覆蓋
string s=" 2 4 8";
stringstream ss;
ss<<s;
string st="1";
ss << st; //ss 2 4 81 沒有空格
//stringstream沿用需清空之前的資料
ss.str(""); //只用這個會讀到EOF
ss.clear(); //只用這個會僅清掉EOF接續之前放入的資料
//少一行都會出錯
```
## :speak_no_evil:struct結構
:::success
把多個項目包起來
:::
### 語法
```c++=
struct someone{
char name[10];
int age;
int height;
int weight;
};
int main() {
struct someone s1,s2; //宣告
strcpy(s1.name, "Lisa"); //把"Lisa"複製到s1的name
s1.age = 18;
s1.height = 155;
s1.weight = 40;
cout<<"name:"<<s1.name<<"\n"; //name:Lisa
cout<<"age:"<<s1.age<<"\n"; //age:18
cout<<"height:"<<s1.height<<"\n";
cout<<"weight:"<<s1.weight<<"\n\n";
strcpy(s2.name, "Gigi");
s2.height = 155;
s2.age = 18;
s2.weight = 40;
cout<<"name:"<<s2.name<<"\n";
cout<<"age:"<<s2.age<<"\n";
cout<<"height:"<<s2.height<<"\n";
cout<<"weight:"<<s2.weight<<"\n";
return 0;
}
```
## :speak_no_evil:遞迴
:::success
呼叫自己,注意要設停止點
:::
### 語法
```c++=
//和函式差不多
int f(int n) //5
{
if(n==1)
return 1;
else
return n*f(n-1);
}
int main()
{
int a=5;
cout<<f(a); //120
}
```
```mermaid
graph LR
n=5--呼叫f-->n=4--呼叫f-->n=3--呼叫f-->n=2--呼叫f-->n=1
subgraph 相乘1
n=1-->n=2
end
subgraph 相乘2
n=2-->n=3
end
subgraph 相乘3
n=3-->n=4
end
subgraph 相乘4
n=4-->n=5
end
```
#### 以上程式可得f(a)=1\*2\*3\*4\*5=120
{"metaMigratedAt":"2023-06-17T23:43:02.206Z","metaMigratedFrom":"Content","title":"C++學習筆記","breaks":false,"contributors":"[{\"id\":\"86a0847a-d61d-4de4-b42b-f29298fa1683\",\"add\":5656,\"del\":5788},{\"id\":\"77c87dd5-e867-4d1e-9ffb-d9f8a48be8aa\",\"add\":215,\"del\":0},{\"id\":\"6f970a44-6844-4734-b993-a47e8a21ce5c\",\"add\":12779,\"del\":3243}]"}