--- title: C++教室第二節社課 slideOptions: # 簡報相關的設定 theme: blood # 顏色主題 transition: 'slide' # 換頁動畫 parallaxBackgroundImage: 'https://c.wallhere.com/photos/a5/a8/Neon_Genesis_Evangelion_mech_EVA_Unit_13-1319035.jpg!d' --- C++教室教學講義 === >[name=Howard] [time=September 18th] [color=#333] ###### tags:`tcirc` `社課` ---- [TOC] 第二節社課 === ---- ## 複習時間 ---- ## 運算式與運算子 運算式由運算元及運算子所組成。運算元可以是常數、變數,運算子就是我們在數學中常見的運算符號( +、-、*、/ )等。 C++里也提供許多的運算子,除了一般的數學運算,還可以做邏輯判斷,是判斷式中不可或缺的角色。 ---- ## 設定運算子( = ) 其實在上節社課就有用到了,雖然作為數學式中的等於符號,但當你在C++中用「等於」去解讀設定運算子可能會讓你吃了大虧。 ---- 先看看下面這行程式碼。 ```c++ num = num + 1 ``` 變數num怎麼會等於num再加上1。 1=1+1,數學世界崩毀:boom:。 <span>當然沒有。<!-- .element: class="fragment" data-fragment-index="1" --></span> <span>其實「=」的真正意義在於把後面那項的值賦予(asign)給前項。也就是將num的值加1後再賦予num。<!-- .element: class="fragment" data-fragment-index="2" --></span> ---- ## 算術運算子 大家都有小學畢業,不多作介紹。 <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcQUcKn_fRYPsWlhnhNGlZxNUwIB2t77yWQ8RA&usqp=CAU" width="50%" height="50%" /> ---- 取餘數可能會比較難理解,如果我讓17對5取餘數,就是讓17除以5之後求餘數的意思。 ```c++ cout<<17%5; ``` ``` /*OUTPUT--- 2 ------------*/ ``` ---- ## if判斷與關係運算子 if是我們在做條件判斷時常見的語法,實際用法如下 ```c++ if(條件判斷) 敘述; else if(條件判斷) 敘述; else 敘述; ``` 當if後面的括號內容為真,則程式會執行後段的敘述,and vice versa。 當第一個if判斷不成立時便進入else if的判斷,接著還是不成立時才會執行else所含的敘述。 ---- 補充: 當然也可以只進行一個判斷就好,後面else if和else的部分視情況使用。(if 和else只能在頭尾,而else if 可以一直疊加) `p.s: 若程式敘述不只一行,需要用大括號把該串程式碼包住` ```c++ if(條件判斷){ 敘述; 敘述; 敘述; } ``` ---- 常見的關係運算子如下 <img src="https://gblobscdn.gitbook.com/assets%2F-L_r09305cCOiVsKX4GC%2F-LdbqvVPPV8YTT6nTmP5%2F-Ldbr64OK6YfiRlgsfaW%2F9.2.2.png?alt=media&token=d8b0cfb0-af94-4130-aaf0-71948d26c418" width="100%" height="100%" /> 千萬注意!判斷是否等價時是「==」,不要搞錯了! ---- 看一下範例程式 ```c++= #include<iostream> using namespace std; int main(){ bool a=true,b=false; int x=3,y=2; if(a) cout<<"a is true"<<"\n"; if(b) cout<<"b is true"<<"\n"; if(x>y) cout<<"x is bigger than y"<<"\n"; if(y>x) cout<<"y is bigger than x"<<"\n"; } ``` ``` /*OUTPUT--- a is true x is bigger than y ------------*/ ``` ---- ###### 小小提醒:if的判斷只發生在一開始 ```c++= #include<iostream> using namespace std; int main(){ int x = 100; if (x == 100){ x = 50; cout << x; } } ``` ``` /*OUTPUT--- 50 ------------*/ ``` ---- ## 邏輯運算子 邏輯運算子可以幫助我們在多個條件判斷中做邏輯運算 | 邏輯運算子 | 意義 | 邏輯 | | ---------- | ------- | ---- | | && | And,且 | 交集(∩) | | \|\| | Or,或 | 聯集(∪) | ---- 練習一下吧~ ```c++= #include<iostream> using namespace std; int main(){ int a = -50,b = 75; if (a > 0&&b > 0) cout << "Full positive!\n"; if (a > 0||b > 0) cout << "Half positive!\n"; if (a > b&&b > a) cout << "How???\n"; if (a == b||(a > 0&&(b <= a||a != b))) cout << "Yes."; else if (a != b||a-b > a+b) cout << "Ok..."; else cout << "No!"; } ``` ---- ``` /*OUTPUT--- Half positive! Ok... ------------*/ ``` ---- ## 迴圈 程式是為了做我們做不到的事---多半是一些很花時間的事。與其一個一個給電腦下指令,利用迴圈(loop)可以使電腦重複執行多次指令,節省程式碼的複雜度。以下介紹幾種常用的迴圈: ---- ### for loop ``` c++= for(INITIALIZATION; CONDITION; AFTERTHOUGHT){ code; code; ... } for(初始化;條件;遞增){ code; code; ... } ``` 初始化:在迴圈開始前執行的指令。(可作宣告、賦值及各種其他指令) 條件:是一個判斷式,每一次迴圈開始時做判斷,如果回傳為false則結束迴圈。 遞增:每次迴圈結束會執行的指令。 ---- #### 各式各樣的for loop :) ```c++= #include<iostream> using namespace std; int main(){ for(int a = 0;a < 5;a++){ //a++ -> a = a + 1 cout << "ayy\n"; } for(int x = 135,y = 35;y != 0;cout << x << ' ' << y << '\n'){ x = x%y; swap(x,y); //交換x,y的值 } for(int q = 5;q >= 0;){ q -= 2; cout << q << ' '; } } ``` ---- ``` /*OUTPUT--- ayy ayy ayy ayy ayy 35 30 30 5 5 0 3 1 -1 ------------*/ ``` ---- ### while loop ``` c++= while(CONDITION){ code; code; ... } while(條件){ code; code; ... } ``` ---- ```c++= #include<iostream> using namespace std; int main(){ int n = 4; while(n){ n--; cout << n << ' '; } int t = 9; cout << '\n'; while(t--){ //check then decrease cout << t << ' '; } int k = 9; cout << '\n'; while(--k){ //decrease then check cout << k << ' '; } } ``` ---- ``` /*OUTPUT--- 3 2 1 0 8 7 6 5 4 3 2 1 0 8 7 6 5 4 3 2 1 ------------*/ ``` ---- ### do-while loop ``` c++= do{ code; code; ... }while(CONDITION); do{ code; code; ... }while(條件); ``` ---- ```c++= #include<iostream> using namespace std; int main(){ int n = 4; do{ cout << n; }while(n == 3); int m = 4; while(m == 3){ cout << m; } } ``` ``` /*OUTPUT--- 4 ------------*/ ``` ---- ### break/continue #### break: 直接結束迴圈。 #### continue: 跳過此次迴圈的剩餘程式,直接開始下一次迴圈。 ---- ```c++= #include<iostream> using namespace std; int main(){ for(int a = 0;a < 10;a++){ if (a == 5) continue; cout << a << ' '; } cout << '\n'; int k = 10; do{ cout << k << ' '; k--; if (k == 7) break; }while(k >= 5); } ``` ``` /*OUTPUT--- 0 1 2 3 4 6 7 8 9 10 9 8 ------------*/ ``` ---- ## Switch語法 寫很多if是不是有點累? ```c++= switch(condition){ //must be integer!!! case number:{ code; code; ... break; //IMPORTANT!!! } case number2:{ ... } default:{ ... } } ``` 用法:檢查condition(必須為整數/char/bool!)的數值,並執行相對應的case。(注意:需要加上break,否則所有下面的case都會執行) default:當所有case都無法對應時執行。 ---- ```c++= #include<iostream> using namespace std; int main(){ int k; cin >> k; switch(k){ case 75:{ cout << "It's 75!\n"; break; } case 76:{ cout << "It's 76!\n"; break; } default:{ cout << "I only know 75 and 76...\n"; break; } } } ``` ---- ``` /*INPUT1--- 75 ------------*/ /*INPUT2--- 76 ------------*/ /*INPUT3--- 77 ------------*/ ``` ``` /*OUTPUT1--- It's 75! ------------*/ /*OUTPUT2--- It's 76! ------------*/ /*OUTPUT3--- I only know 75 and 76... ------------*/ ``` ---- ##### 把break去掉? ``` /*OUTPUT1--- It's 75! It's 76! I only know 75 and 76... ------------*/ /*OUTPUT2--- It's 76! I only know 75 and 76... ------------*/ /*OUTPUT3--- I only know 75 and 76... ------------*/ ``` ---- ### 補充:二元運算子 ```c++= (condition)?(value1):(value2) ``` 當condition成立時,回傳value1,否則回傳value2。 value1,value2要是同一個型別(或可做轉換)。 ---- ```c++= #include<iostream> using namespace std; int main(){ int k; cin >> k; cout << ((k < 0)?k:-k); } ``` ``` /*INPUT1--- 1023 ------------*/ /*INPUT2--- -888 ------------*/ ``` ``` /*OUTPUT1--- -1023 ------------*/ /*OUTPUT2--- -888 ------------*/ ``` ---- ##### 多層迴圈範例(九九乘法表) ```c++= #include<iostream> using namespace std; int main(){ for(int a = 1;a <= 9;a++){ for(int b = 1;b <= 9;b++){ cout << a << "*" << b << " = " << a*b << ' '; } cout << '\n'; } } ``` ---- ``` /*OUTPUT--- 1*1 = 1 1*2 = 2 1*3 = 3 1*4 = 4 1*5 = 5 1*6 = 6 1*7 = 7 1*8 = 8 1*9 = 9 2*1 = 2 2*2 = 4 2*3 = 6 2*4 = 8 2*5 = 10 2*6 = 12 2*7 = 14 2*8 = 16 2*9 = 18 3*1 = 3 3*2 = 6 3*3 = 9 3*4 = 12 3*5 = 15 3*6 = 18 3*7 = 21 3*8 = 24 3*9 = 27 4*1 = 4 4*2 = 8 4*3 = 12 4*4 = 16 4*5 = 20 4*6 = 24 4*7 = 28 4*8 = 32 4*9 = 36 5*1 = 5 5*2 = 10 5*3 = 15 5*4 = 20 5*5 = 25 5*6 = 30 5*7 = 35 5*8 = 40 5*9 = 45 6*1 = 6 6*2 = 12 6*3 = 18 6*4 = 24 6*5 = 30 6*6 = 36 6*7 = 42 6*8 = 48 6*9 = 54 7*1 = 7 7*2 = 14 7*3 = 21 7*4 = 28 7*5 = 35 7*6 = 42 7*7 = 49 7*8 = 56 7*9 = 63 8*1 = 8 8*2 = 16 8*3 = 24 8*4 = 32 8*5 = 40 8*6 = 48 8*7 = 56 8*8 = 64 8*9 = 72 9*1 = 9 9*2 = 18 9*3 = 27 9*4 = 36 9*5 = 45 9*6 = 54 9*7 = 63 9*8 = 72 9*9 = 81 ------------*/ ``` ---- ## 宣告的規則 宣告變數是寫程式很重要的一件事。其中存在一些規則,必須作注意。 1.變數要在宣告後才能使用。 2.宣告的有效範圍是該宣告所在區塊(block),即{ 和 }之間的範圍。所以綜合第一點:宣告的有效範圍為宣告位置~該block的結束。 3.可在main函式外做宣告(又稱全域宣告),全域宣告的變數可在程式的任意位置使用。 4.for loop的初始化宣告在loop進行時皆可使用。 ---- ```c++= #include<iostream> using namespace std; char k = 'K'; int main(){ cout << x; //NOT OK cout << k; //OK int x = 2096; cout << x; //OK for(int a = 0;a <= 5;a++){ x += 1; //OK x += q; //NOT OK a += x; //OK int q; x += q; //OK cout << k;//OK } a = x; //NOT OK cout << k; //OK } ``` ---- ![](https://i.imgur.com/RPE5KPY.png) ---- ### 解題技巧:多點測資 有些時候,題目會要求不斷讀取資料直到檔案結束(EOF),這個時候可以用一個while loop讀取資料,可是要怎麼偵測檔案結束並跳出迴圈呢?其實當我們輸入資料時,資料會送到cin這個物件中,當cin讀取資料時發現無法轉換的資料(ex:在讀取int時遇到英文字母)或是換行,cin會停止讀取資料,並將讀取到的資料放入目標變數中。下一次cin就從該位置開始。**注意讀取失敗的資料不會消失。** ---- 當cin讀取失敗,有許多方法可以偵測: 1.cin.fail():當cin讀取失敗時此函式回傳true。 2.cin.good():當cin讀取失敗時此函式回傳false。 3.cin.eof():與前兩者不同,只有在讀取到EOF時回傳true。 4.cin:cin本身可以轉換成bool,在讀取失敗時會回傳false。 ---- ```c++= #include<iostream> int main(){ using namespace std; while(1){ //infinite loop int k; cin >> k; if (!cin) break; //version 1 if (cin.fail()) break; //version 2 if (!cin.good()) break; //version 3 if (cin.eof()) break; //version 4 } } ``` ---- ## 小試身手~ [b018: 可樂成癮患者](https://judge.tcirc.tw/ShowProblem?problemid=b018) [b015: 數字的顏色](https://judge.tcirc.tw/ShowProblem?problemid=b015) [b023: 十二生肖](https://judge.tcirc.tw/ShowProblem?problemid=b023) [b013: 閏年問題](https://judge.tcirc.tw/ShowProblem?problemid=b013) 挑戰題:[b038: 存量問題](https://judge.tcirc.tw/ShowProblem?problemid=b038) ---