TCIRC C++教學講義 === >[name=張皓凱、沈奕呈][time=Oct 15,2021] ###### tags:`tcirc` `社課` `C++` `台中一中電研社` --- 第二節社課 === [TOC] --- ## 電研 講義都會公告在社網上 [社網:tcirc.tw](https://tcirc.tw/) [IG:tcirc_39th](https://www.instagram.com/tcirc_39th/) ![ig QRcode](https://i.imgur.com/4hyS6GM.png) [online judge:judge.tcirc.tw](https://judge.tcirc.tw/) --- ## 資料型態之間的轉換 ---- ### 數字 不同的資料型態在計算時會發生一些變換,在撰寫程式時必須特別注意以下規則: 1. 當整數和浮點數進行運算時,統一轉換為浮點數運算。否則一律以整數運算 2. 當2個大小不同的整數/浮點數做運算時,較大的型別會被採用。short一律當作int計算 3. 字元做運算時,統一轉換為整數 4. 在賦值時,「計算結果」統一轉換為該變數的資料型態(計算時依舊為原計算模式)利用(資料型態)可作強制轉換 ---- ```cpp= #include<iostream> using namespace std; int main(){ double a = 5000/3; //"5000/3" is calclated in int then assigned to double cout << a << '\n'; double b = 5000.0/3; //"5000.0/3" is calculated in double then assigned to double cout << b << '\n'; double c = 2.25; int d = c; //double is converted to int before assigning cout << d << ' ' << c*d << ' ' << (int)(c*d) << '\n'; char k = 'A'; //char is converted to int during compution cout << k + 5 << ' ' << k + 'A' << ' ' << '\n'; short x = 5000; cout << x*x << ' '; //short is converted to int during compute x = x*x; //int is converted back to short during assignment cout << x << '\n'; } ``` ``` /*OUTPUT--- 1666 1666.67 2 4.5 4 70 130 25000000 30784 ------------*/ ``` ---- ### 數字及字元 可以利用`(int)`及`(char)`對字元及整數進行轉換,轉換結果會依照ASCII碼。若是想要將`'0'~'9'`之間的字元轉換為`0~9`的數字,可以透過`-'0'`來達成。 ```cpp= #include <iostream> using namespace std; int main(){ int a = 65; char b = 'a'; char c = '5'; int d = c; int e = c - '0'; cout << (char)a << " " << (int)b << endl; cout << d << " " << e; } ``` ``` /*OUTPUT--- A 97 53 5 ------------*/ ``` --- ## 溢位 既然資料型態有範圍,那如果數字超出了範圍會怎樣?當變數的值超出範圍,我們就稱這個情況為溢位(overflow)。如果我們宣告(int)一個整數i的值為2147483647,值的範圍會落在int的範圍內。但是這時我們使 i+1 便會發生溢位的狀況,這時的i會回到int的最小值-214748348。 --- ## bool bool(布林)是一種邏輯資料型態,所能存放的只有0(false)和1(true),預設數值為0。在賦值時可以設定為true, falae或者是任意數字,當設定為數字時,若數字為非零整數,則變數值為1,若為零,則變數值為0。 ---- ```cpp= #include <iostream> using namespace std; int main(){ bool a=true; bool b=0; bool c=9201.32; cout << a << " " << b << " "<< c; } ``` ``` /*output--- 1 0 1 ------------*/ ``` --- ### 運算 布林值的運算又稱為邏輯運算,常見有`&&`(且)、`||`(或)和`!`(非),其運算結果如下: | && | 0 | 1 | |:--------:|:---:|:--------:| | 0 | <font color="#f00">0</font> | <font color="#f00">0</font> | | 1 | <font color="#f00">0</font> | <font color="#f00">1</font> | ---- | \|\| | 0 | 1 | |:--------:|:--------:|:--------:| | 0 | <font color="#f00">0</font> | <font color="#f00">1</font> | | 1 | <font color="#f00">1</font> | <font color="#f00">1</font> | | | 0 | 1 | |:----:|:----:|:----:| | ! | <font color="#f00">1</font> | <font color="#f00">0</font> | ---- `&&`跟`||`的寫法與加減乘除相同,而`!`則是加在布林值之前 ```cpp= #include <iostream> using namespace std; int main(){ bool a=1; bool b=0; bool c=a&&a; cout << c << " "; c=!(b||true); cout << c; } ``` ``` /*output--- 1 0 ------------*/ ``` --- ## 比較運算子 比較運算子是用於比較兩邊關係的運算子,以下將列出常用的比較運算子: ---- | 比較運算子 | 意義 | | -------- | -------- | | > | 大於 | | < | 小於 | | == | 相等 | | >= | 大於等於 | | <= | 小於等於 | | >< | 大於小於,不相等 | | != | 不相等 | ---- <font color="#f00">注意!</font> * `=`是設定運算子,如果要比較是否相等要使用`==` * 若包含兩個字元的比較運算子不可以前後寫相反,例如:`<=`不可以寫成`=<` --- ## 條件式 條件式是我們在程式中用來比較關係時用的,最常見是用於比較兩個數值。結果為布林值,若敘述正確為`true(1)`否則為`false(0)`,其寫法如下: ``` 變數/常數 比較運算子 變數/常數 ``` ---- ```cpp= #include <iostream> using namespace std; int main(){ int i=5, j=7; bool a = i<=6; bool b = i==j; cout << a << " " << b << " "; } ``` ``` /*output--- 1 0 ------------*/ ``` --- ## 條件敘述 if-else 條件敘述是指程式依照特定條件的真或假而選擇不同的執行路徑,最常見的條件敘述就是if-else。 ---- ### 基本寫法 當小括號內的條件式或布林值為true時,就會執行大括號內的程式,否則直接繼續執行if後的程式。 ```cpp= if(條件式或bool){ code; ... } ``` * 小括號後<font color='#f00'>不需要</font>加分號 * 大括號後<font color='#f00'>不需要</font>加分號 * 條件式<font color='#f00'>不需要</font>加分號 * 大括號內的每一行程式都<font color='#f00'>需要</font>加分號 ---- ```cpp= #include <iostream> using namespace std; int main(){ bool a=false; if(a){ cout << "a=true"; } if(7>=6){ cout << "7 >= 6"; } } ``` ``` /*output--- 7 >= 6 ------------*/ ``` --- ### else 當小括號內的條件式或布林值為true時,就會執行第一個大括號內的程式,否則執行else後的大括號內程式。 ```cpp= if(條件式或bool){ code; ... }else{ code; ... } ``` ---- ```cpp= #include <iostream> using namespace std; int main(){ int a=5; int b=10; if(a>b){ cout << "a>b"; }else{ cout << "a<=b"; } } ``` ``` /*output--- a<=b ------------*/ ``` --- ### 巢狀if 巢狀if指的是if當中還有if,像鳥巢一樣一層一層的。 ```cpp= if(條件式或bool){ code; if(條件式或bool){ code; } code; }else{ code; if(條件式或bool){ code; } code; } ``` ---- ```cpp= #include <iostream> using namespace std; int main(){ int a=5; int b=10; int c=7; if(a>b){ cout << "a>b and "; if(b>c){ cout << "b>c"; }else{ cout << "b<=c"; } }else{ cout << "a<=b and "; if(b>c){ cout << "b>c"; }else{ cout << "b<=c"; } } } ``` ``` /*output--- a<=b and b>c ------------*/ ``` --- ### else if else if可以把它看成是一種朝狀if的簡寫。當else當中只有if時就可以將if哪出括號外變成else if。 ```cpp= if(condition A){ code A; }else{ if(condition B){ code B; }else{ code C; } } ``` ```cpp= if(condition A){ code A; }else if(condition B){ code B; }else{ code C; } ``` ---- ```cpp= #include <iostream> using namespace std; int main(){ int a=19; int b=10; if(a>b){ cout << "a>b"; }else if(a==b){ cout << "a=b"; }else{ cout << "a<b"; } } ``` ``` /*output--- a>b ------------*/ ``` ---- 在if-else當中,if是可以單獨存在,else與else if不行。在一組包含if,else if,else的程式當中,if只能有一個並且在最上面,else if可以有無限多個,else只能有一個並且在最後。 --- ### 簡寫 ---- 當if,else if, else後的大括號中只有一行程式時,可以將大括號去掉,直接接在小括號後即可 ```cpp= if(condition){ code; }else if(conditioin){ code; }else{ code; } ``` ```cpp= if(condition)code; else if(condition)code; else code; ``` ---- 當只有if及else,且大括號內接只有一行程式碼時,可以使用`?:`取代。 ```cpp= if(condition){ code A; }else{ code B; } ``` ```cpp= (condition)? code A : code B; ``` <font color="#f00">注意:</font>只需要有一個分號 ---- ```cpp= if(a>b){ cout << "a>b"; }else{ cout << "a<=b"; } ``` ```cpp= (a>b)? cout << "a>b" : cout << "a<=b"; ``` --- ### 題目練習:[b013: 閏年問題](https://judge.tcirc.tw/ShowProblem?problemid=b013) ### 題目練習:[b014: 串串的三角形](https://judge.tcirc.tw/ShowProblem?problemid=b014) --- ## switch(補充) 有天串串的朋友電電,出了一道題來為難整天埋頭寫程式的串串 - 當數字=1,執行I - 當數字=2,執行H和I - ... - 當數字=9,執行A.B.C...I(九個) - 如果是3.4.6.7則執行三次A - 其他數字則不執行 ---- 當條件很零散,或多種條件做同一件事情的時候 寫那麼多if是不是很累? 試試switch吧! ```cpp= #include<iostream> using namespace std; int main(){ //成績等第分級 int x; while(cin>>x){ switch(x/10){//別忘了int除int會捨去餘數 case 10: case 9:{//90~99和100分 cout<<"excellent"; break; } case 8:{//80~89分 cout<<"great"; break; } case 7:{//70~79分 cout<<"good"; break; } case 6:{//60~69分 cout<<"so so"; break; } default:{//其他(不及格) cout<<"bad"; break; } } cout<<'\n'; } return 0; } ``` ---- switch的用法: - switch的條件須為 `int`,`bool` 或 `char` 型態的變數 - 需對應相應型態的case(列舉的方式) - 3.當符合某個case會執行以下所有case中的程式碼直到 `break;` - 4.`default` 當所有case都無法對應時執行 ---- 所以寫switch須特別注意前三點, <font color="#f00">注意: 千萬記得加break!!!</font> 否則下面的case都會執行 因為switch的第一點限制,條件還要一個一個寫,所以使用switch的頻率比if低很多,但是當條件零散的時侯,switch可以幫你省下很多時間喔! ---- 再回來看看一開始的問題 (看來電電學switch的時候在玩電腦😏) ```cpp= #include<iostream> using namespace std; int main(){ int n; while(cin>>n){ cout<<n<<": "; switch(n){ case 9: //a~i cout<<'A'<<' '; case 8:{//b~i cout<<'B'<<' '; cout<<'C'<<' '; cout<<'D'<<' '; } case 5:{//e~i cout<<'E'<<' '; cout<<'F'<<' '; cout<<'G'<<' '; } case 2: //H.I cout<<'H'<<' '; case 1:{//I cout<<'I'<<' '; break; } //A*3 case 3: case 4: case 6: case 7:{ for(int i=0;i<3;i+=1) cout<<'A'<<' '; break; } } cout<<'\n'; } return 0; } ``` ---- ``` /*input--- 9 8 7 6 5 4 3 2 1 ------------*/ ``` ``` /*output--- 9: A B C D E F G H I 8: B C D E F G H I 7: A A A 6: A A A 5: E F G H I 4: A A A 3: A A A 2: H I 1: I ------------*/ ``` --- ## 迴圈(loop)🔄 有時候我們寫程式是因為**重複做類似的事情**會花我們很多時間,而讓電腦去做,可以省下需多時間。 使用**迴圈**可以重複執行某段程式,減少程式複雜性,以下會介紹常見的幾種loop --- ### while while loop的寫法是 `while(條件){}` - 每當條件(邏輯判斷式)成立, 就會執行 `{}` 裡面的程式碼一次 - 當條件不成立, 則程式就會略過 `{}` 裡的內容繼續往下跑 ---- ```cpp= #include<iostream> using namespace std; int main(){ //example 1 int n=9; while(n){//當數字不等於0在bool運算皆成立 cout<<n; n--; } cout<<'\n'; //example 2 int i=1,grade; while(i<=5){ cin>>grade; if(grade>=60)//一行解決不須{} cout<<i<<":及格"<<'\n'; else cout<<i<<":不及格"<<'\n'; i++; } return 0; } ``` ---- ``` /*input--- 65 60 59 100 0 ------------*/ ``` ``` /*output--- 987654321 1:及格 2:及格 3:不及格 4:及格 5:不及格 ------------*/ ``` --- ### 題目練習:[b017: 病毒的增生](https://judge.tcirc.tw/ShowProblem?problemid=b017) --- ### for 前一頁的第二個while loop花了三行程式碼分別初始化變數、判斷條件、固定對宣告的變數運算 有沒有辦法把這幾個有關連的事寫在一起呢?這時候就用for loop吧! ---- 如果程式要做的事情跟執行次數有關的話(比如說第一天花一元,第二天花兩元...或是記錄班上每個座號的身高體重換算BMI)這時候用 `for` 會比 `while` 方便很多 ---- for loop的寫法是 `for(初始化;條件;每次迴圈結束後做的事){}` - 要記得 `for` 的`()` 裡面這三個要素, 還有每個要素之間要用 `;` 隔開, - 如果不需要某個要素的功能的話 可以不用寫該要素,但是**分號不能省略**!!! ---- ```cpp #include<iostream> using namespace std; int main(){ /* compare with while loop ---------while loop example 2---------- int i=1,grade; while(i<=5){ cin>>grade; if(grade>=60) cout<<i<<":及格"<<'\n'; else cout<<i<<":不及格"<<'\n'; i++; } */ //------example 2 using for loop-------- for(int i=1,grade;i<=5;i++){ cin>>grade; if(grade>=60) cout<<i<<":及格"<<'\n'; else cout<<i<<":不及格"<<'\n'; } cout << endl; //輾轉相除法 for(int x=135,y=35 ; y!=0 ; cout<<x<<' '<<y<<'\n'){ x%=y; swap(x,y);//交換x,y } cout << endl; //example 4 for(int q=5;q>0;){ q-=2; cout<<q<<' '; } return 0; } ``` ---- ``` /*input--- 65 60 59 100 0 ------------*/ ``` ``` /*output--- 1:及格 2:及格 3:不及格 4:及格 5:不及格 35 30 30 5 5 0 3 1 -1 ------------*/ ``` --- ### 題目練習:[b021: 電電找因數](https://judge.tcirc.tw/ShowProblem?problemid=b021) --- ### do while 前面 `while` 是先判斷條件再執行程式碼, - 但當無論條件如何,都必須先執行一次loop裡的一次程式碼時,可以使用 `do while` ---- - `do while` 是先執行再判斷條件,保證你可以至少執行一次迴圈裡的程式 - 除非有**一開始就不符合條件**的情況,不然`while`和`do while`跑出來的結果基本上是一樣的 ---- ```cpp= #include<iostream> using namespace std; int main(){ //example cout<<"whlie loop: "; int n=9; while(n){ cout<<n; n--; } cout<<'\n'<<"do-while loop: "; int a=9; do{ cout<<a; a--; }while(a); cout<<'\n'; //compare with example cout<<"whlie loop 2: "; n=9; while(n==8){ cout<<n; n--; } cout<<'\n'<<"do-while loop 2: "; a=9; do{ cout<<a; a--; }while(a==8);//after do the first time, //the codition allow you to do the second time cout<<'\n'; return 0; } ``` ---- ``` /*output--- whlie loop: 987654321 do-while loop: 987654321 whlie loop 2: do-while loop 2: 98 ------------*/ ``` --- ### break/continue #### break 直接結束迴圈 #### continue 跳過此次迴圈的剩餘程式,直接開始下一次迴圈 ---- ```cpp= #include<iostream> using namespace std; int main(){ for(int i=0;i<10;i+=1){ if(i==4) continue; if(i==7) break; cout<<i<<' '; }//example 1 cout<<'\n'<<'\n'; int k=10; while(k--){//先判斷再-1 if(k%2==0) continue; cout<<k<<' '; if(k==8) break;//被continue跳過 if(k==3) break; }//example 2 return 0; } ``` ---- ``` /*output--- 0 1 2 3 5 6 9 7 5 3 ------------*/ ``` --- ## 區塊 --- ## 題目練習 * [b020: 慎思湖的倒影](https://judge.tcirc.tw/ShowProblem?problemid=b020) * [c003: Ⅲ.相親相愛](https://judge.tcirc.tw/ShowProblem?problemid=c003)
{"title":"C++教學講義-第二週","slideOptions":{"theme":"blood","transition":"slide"}}
    726 views
   owned this note