---
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

Code::blocks是非常好用的IDE,對於新手來說非常好上手,顏色字體設定那些的調起來也很方便
### Dev C++
~~Dev C++超廢 我不懂為甚麼還有人在用這種垃圾~~
超久沒有更新版本,不能用C++17(除非你手動更新編譯器版本),有時候會出現很詭異的bug
我是非常不推薦使用啦 更新編譯器比起設定接下來要提到的Sublime Text還要麻煩 不如不用
### Sublime text
基本上Sublime text只是個文字編輯器(但是外觀非常簡潔好看)
要設定好能夠一鍵編譯需要一定程度的基本知識
對新手而言或許有些複雜
詳細步驟可以參考學長寫的教學:<br/> https://hackmd.io/@PixelCat/BJwmD9SpF https://hackmd.io/@H1deonbruH/BJEReEog3
### VScode
跟 Sublime Text 差不多,但有更多的東西可以改,也有更多更好的插件。
### Vim
痾...
放這裡純粹是推坑:moyai:,設定比sublime text複雜一些
建議有興趣又很閒的**再**自己研究,這邊給一些資源讓你們可以玩看看
vimrc相關:
http://wiki.csie.ncku.edu.tw/vim/vimrc
https://github.com/flazz/vim-colorschemes
插件相關:
https://github.com/junegunn/vim-plug
其他:
[vim cheat sheet](https://vim.rtorr.com/lang/zh_tw)
[筆者的vimrc設定檔](https://github.com/chengyin30069/competitive-programming)
## 變數
### 關於變數:甚麼是變數?
>維基百科:變數可以指在電腦記憶體裏存在值的被命名的儲存空間。
變數的定義非常的廣泛 可以儲存資料的都可以被稱為變數
字串、浮點數、整數等都算
而C/C++在使用變數前必須先宣告變數
像這樣
```cpp=
int x;
float y;
string ff;
long long big;
```
### 整數變數:
各種變數的儲存範圍
bool :0,1
short :$\pm(2^{16}-1)=\pm32768$
int :$\pm(2^{32}-1)=\pm2,147,483,647$
long long :$\pm(2^{64}-1)=\pm9,223,372,036,854,775,807$
#### {小技巧|毒瘤}
#define int long long
優點:不用每次都檢查是哪些變數溢位了
缺點:有些題目會故意卡你記憶體大小
### 浮點數:
float:七位數
double:十五位數
long double:視作業系統與編譯環境而定 精度保證大於等於double
char:儲存單一字元
string:儲存一串字元 底層是以STL容器實現的
### 輸入輸出
```cpp=
int a;
scanf("%d", &a);
printf("%d", a);
```
但這個太複雜了因為難寫+要打型態,所以有更好的
```cpp=
int a;
cin>>a;
cout<<a;
```
雖然這個比較慢,但其實前面加了輸入優化之後就一樣快了
```cpp=
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
```
### 運算子
```cpp=
int a,b,c;
//四則運算
a=b+c;
a=b-c;
a=b/c; //會自動取整
a=b*c;
a=b%c; //取餘
//bitwise 運算
a=b|c; // or
a=b&c; // and
a=b^c; // xor
a=b<<1; a=b>>1; //往左/右移一位
```
### if else 判斷式
```cpp=
if(條件){
做事;
}
else if(條件){
做事;
}
else{
做事;
}
```
:::spoiler 觀看下列兩段程式,想一想它們的差異
```cpp=
if(判斷式)
{
執行程式;
}
else if(判斷式)
{
執行程式;
}
else
{
執行程式
}//只會執行其中一個
```
```cpp=
if(判斷式)
{
執行程式;
}
if(判斷式)
{
執行程式;
}
if(判斷式)
{
執行程式;
}//只要條件符合 三個if裡的程式都會執行
```
:::
### for、while 迴圈
**for**
```cpp=
for(一開始做的事;繼續的條件;每次結束後做的事)
{
做事;
}
for(int i=1;i<=n;i++){
cout<<i<<' '; // 1 2 3 ... n-1 n
}
```
**while**
```cpp=
while(判斷式)
{
執行式;
}
```
判斷{->|如果符合}執行->...->判斷{->|不符合}跳出迴圈
```cpp=
int i=1;
while(i<=n){
cout<<i<<' '; // 1 2 3 ... n-1 n
i++;
}
```
**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時不會執行
}
```
### 陣列
有時候當你想讀取一系列的變數的時候
陣列會是一個很好的選擇
陣列宣告:
```cpp=
int a[1000];
long long ff[500];
double data[2000];
char l[100];
//或是用變數的大小
int a[n];
```
會爛的宣告方式:
```cpp=
int n;
int a[n];
cin>>n;
```
:::spoiler 為甚麼會爛?
在 main 裡宣告整數變數會先被賦值成亂數,宣告陣列的時候就會爛掉,應該要在變數的值確定之後才宣告。
:::
<br/>
陣列讀取
```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=
型態 function(傳入的值){
做事;
有必要的話回傳東西;
}
```
C++的函式分兩種
void:不回傳值
其他:回傳指定值
```cpp=
void function(){
做事;
return;
}
int/char/double... function(){
做事;
return xxx;
}
```
以求費氏數列為例
用void寫的話會長這樣
```cpp=
int fib[100]={-1};
void f(int now)
{
if(now<=2)
{
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)
**呼叫的函式要在上面**
這樣會爛
```cpp=
int main(){
cout<<f();
}
int f(){
return 1;
}
```
這樣才不會爛
```cpp=
int main(){
cout<<f();
}
int f(){
return 1;
}
```
### struct
將很多資料綁在一起的神奇東西
可以想像成pair的升級版
```cpp=
//總之 各種奇形怪狀的東西只要你想包就可以包進去
struct product
{
int price;
string name;
//還可以包很多東西
};
```
## 其他很讚的東東
### 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裡有預先寫好的std::endl
使用方法就是在cout的時候一起夾起來像這樣:
```cpp=
cout<<"I love Yuubari"<<endl;
```
雖然寫起來很方便
**但是**
endl跟'\n'相比,endl又多再去清除緩衝區
所以用多了可能會造成程式執行過慢
因此一般都建議改用'\n'
不然就是使用`#define endl "\n"`
## Conclusion
感謝很有耐心從開頭看到這裡的你
這份講義多少有點粗糙 但希望能夠幫到你
不論你是剛起步的新手還是稍微有點經驗的選手
祝福你能夠在競賽程式中找到一片天地
當然 資研的DC永遠為你敞開
所以不管白癡的問題也好 艱澀的問題也好
都請多多善用資源 請教你們親愛的競賽教學
最後附上一張我老婆的照片
你看過嗎?你一定沒看過對吧
那就藉由這個機會讓你看吧 :sunglasses:
