---
# System prepended metadata

title: C++基礎語法
tags: [7th 教學]

---

---
title: C++基礎語法
tags: 7th 教學
slideOptions:
  theme: black
  transition: 'slide'
---
<style type="text/css">
.slides {
    text-align: left !important;
}
</style>
# C++基礎語法
#### Author: H1de_on_bruH

## 概要
一些剛入門C++你需要知道的事


## 推薦的編譯環境


### Code::blocks
![](https://i.imgur.com/rUqRper.png)


Code::blocks是非常好用的IDE，對於新手來說非常好上手，顏色字體設定那些的調起來也很方便


### Dev C++

~~Dev C++超廢 我不懂為甚麼還有人在用這種垃圾~~

超久沒有更新版本，不能用C++17(除非你手動更新編譯器版本)，有時候會出現很詭異的bug
我是非常不推薦使用啦 更新編譯器比起設定接下來要提到的Sublime Text還要麻煩 不如不用

### Sublime text

https://packagecontrol.io/packages/CppFastOlympicCoding
這個是筆者最近發現用於Sublime Text的插件
設置上需要更改環境變數
對新手而言或許有些複雜
詳細步驟可以參考[這個連結](https://www.geeksforgeeks.org/setting-up-sublime-text-for-competitive-programming-c-using-fast-olympic-coding-plugin/?ref=rp&fbclid=IwAR13nqQhI2JNBtP0A0xqhSKy76lLcKIim0AewwmL1gXfiiqoqfEWZzB5PJ8)
筆者自己也寫了一篇[中文教程](https://hackmd.io/@H1deonbruH/BJEReEog3)

## 變數


### 關於變數:甚麼是變數?
>維基百科:變數可以指在電腦記憶體裏存在值的被命名的儲存空間。 

變數的定義非常的廣泛 可以儲存資料的都可以被稱為變數
字串、浮點數、整數等都算


而C/C++在使用變數前必須先宣告變數
像這樣
```cpp=
int x;
float y;
string ff;
long long big;
```


### 整數變數:
各種變數的儲存範圍
bool :0,1
short :$0\pm32,767$
int :$0\pm2,147,483,647$
long long :$0\pm 9,223,372,036,854,775,807$


#### {小技巧|毒瘤}
#define int long long
優點:不用每次都檢查是哪些變數溢位了
缺點:有些題目會故意卡你記憶體大小


### 浮點數:
精度:
float:七位數
double:十五位數
long double:視作業系統與編譯環境而定 精度保證大於等於double


字元:
char:儲存單一字元
字串:
string:儲存一串字元 底層是以STL容器實現的
~~其實string應該等STL再提的 但這問題就留給後人來解決吧~~

### 陣列

有時候當你想讀取一系列的變數的時候
陣列會是一個很好的選擇

陣列宣告:
```cpp=
int a[1000];
long long ff[500];
double data[2000];
char l[100];
```

不安全的宣告方式:
```cpp=
int n;
cin>>n;
int a[n];
```
:::spoiler 為甚麼不安全?
因為上方的寫法會讓程式編譯完後才開陣列
當n越大越有可能發生記憶體區段錯誤的問題
:::

陣列讀取
```cpp=
int a[10];
for(int i=0;i<10;i++)cin>>a[i];
```
**陣列的開頭是從0開始的(0-base)**
意即上面程式裡的陣列只有a[0],a[1],a[2]...a[9] 
寫a[10]會戳出陣列範圍 會有不可預料的結果


## 基礎語法

### 標準輸入、輸出

```cpp=
#include<iostream>
using namespace std;
int main()
{
    int n;
    cin>>n;//輸入n
    cout<<n;//輸出n
}
```
### 運算子們

基礎的一些加減乘除大於小於等於之外還有一些別的東西，像是:
% << >> | ^ & 
上面運算子的功能依序是:
取餘數,左移($\times 2^n$),右移($\div 2^n$),或(or),異或(xor),且(and)

### if else 判斷式

觀看下列兩段程式
想一想它們的差異
```cpp=
if(判斷式)
{
    執行程式;
}
else if(判斷式)
{
    執行程式;
}
else
{
    執行程式
}//只會執行其中一個
```

```cpp=
if(判斷式)
{
    執行程式;
}
if(判斷式)
{
    執行程式;
}
if(判斷式)
{
    執行程式;
}//只要條件符合 三個if裡的程式都會執行
```
### for、while 迴圈

**for**
```cpp=
for(1;2;4)
{
    3;
}
```
**while**
執行1->判斷2{->|如果符合}執行3->執行4->判斷2->...->判斷2{->|不符合}跳出迴圈
```cpp=
while(判斷式)
{
    執行式;
}
```
判斷{->|如果符合}執行->...->判斷{->|不符合}跳出迴圈

**break**
break就是讓你的迴圈直接停下來的意思
```cpp=
for(int i=0;i<n;i++)
    if(...)break;
```
需要注意的是break只會跳出一個迴圈
```cpp=
for(int i=0;i<n;i++)
    for(int j=0;j<i;j++)
        if(...)break;//跳出for(int j=0;j<i;j++)
```
**continue**

可以直接跳過迴圈後面的程式
通常用在跳過不需要處理的case
```cpp=
for(int i=0;i<10;i++)
{
    if(i==5)continue;
    執行程式//i=5時不會執行
}
```
### 自定義函數

C++的函式分兩種
void:不回傳值
其他:回傳指定值

以求費氏數列為例
用void寫的話會長這樣
```cpp=
int fib[100]={-1};
void f(int now)
{
    if(now<=2)
    {
        fib[now]=1;
        return;
    }
    if(fib[now]!=-1)return;
    f(now-1),f(now-2);
    fib[now]=fib[now-1]+fib[now-2];
    return;
}
```
int型態的費氏數列
```cpp=
int ff(int now)
{
    if(now<=2)return 1;
    return ff(now-1)+ff(now-2);
}
```

又或是要自訂排序的方式
```cpp=
bool cmp(int a,int b){return a>b;}
int main()
{
    int n;cin>>n;
    int a[100];
    for(int i=0;i<n;i++)cin>>a[i];
    sort(a,a+n,cmp);
}
```
[排序](https://hackmd.io/@nehs-iced-7th/rk7moqETd#/4/5)

### struct

將很多資料綁在一起的神奇東西
可以想像成pair的升級版
```cpp=
//總之 各種奇形怪狀的東西只要你想包就可以包進去
struct edge
{
    int a,b,c;
    vector<int>ff;
    set<int>the;
    map<int,int>m;
    gp_hash_table<int,int>fm;
    std::priority_queue<int,vector<int>,greater<int>>pq;
};
```

## 其他很讚的東東

### define
這是一個非常好用的東西
你可以把文字改成你想要替換的任意東西
compiler在讀你這個文字的時候會自動替換成你定義好的東西
前面提到的 #define int long long
就會讓compiler把你程式你面所有的int都讀成long long
但也正是因為這樣所以不能使用int main() 你得改成signed main()
```cpp=
#include<iostream>
#define int long long
#define float double
#define pb push_back
...
```


### IO優化:

有些{題目|爛題目}會卡你的速度讓你scanf過但cin過不了
這是因為cin,cout和stdin同步的關係
那只要關閉這個同步流就可以達到近乎scanf,printf的速率了
那要如何關掉?
很簡單 只要在程式開始讀輸入前打
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
就能關閉同步流


```cpp=
void solve()
{
    int n;cin>>n;
    while(n--)cout<<"test\n";
}
signed main()
{
    ios::syn_with_stdio(0),cin.tie(0),cout.tie(0);
    solve();
}
```


### endl

iostream裡有個換行叫做endl
使用方法就是在cout的時候一起夾起來像這樣:
```cpp=
cout<<"I love Yuubari"<<endl;
```
雖然寫起來很方便
**但是**
endl跟'\n'相比，endl又多再去清除緩衝區
所以用多了可能會造成程式執行過慢
因此一般都建議改用'\n'
不然就是使用#define end "\n"



## Conclusion 
感謝很有耐心從開頭看到這裡的你
這份講義多少有點粗糙 但希望能夠幫到你
不論你是剛起步的新手還是稍微有點經驗的選手
祝福你能夠在競賽程式中找到一片天地
當然 資研的DC永遠為你敞開
所以不管白癡的問題也好 艱澀的問題也好
都請多多善用資源 請教競賽教學



