--- 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永遠為你敞開 所以不管白癡的問題也好 艱澀的問題也好 都請多多善用資源 請教競賽教學