--- 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 基本上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: ![](https://i.imgur.com/Y26Xmtg.jpg)