--- tags: 2021CRC Extra Resources title: 社課額外補充教材:判斷結構 --- # 社課額外補充教材 : 判斷結構 如果你覺得社課還算輕鬆,這裡提供你一些額外的補充教材。 這些是我們在備課的時候覺得稍微進階,或是篇幅太多,而沒有放在正式社課的內容。 --- 這邊有目錄,左邊也有,可以跳到自己想看的地方 [TOC] --- 建議必看的地方 : * 有關switch case (110資訊學科能力競賽筆試有考OAO) * if - else if結構相關 * 三元運算子(Question mark operator) --- ### 有關 switch case #### 基本架構 ```cpp= switch(a) //a為變數 { case b: //write something break; //選擇性的 case c,d: //也可像這樣進行多個判斷 //write something break; //選擇性的 . . . default: //如果其他的都不符合才會執行 } ``` * 注意!b ,c ,d只能放值,不可放條件判斷 * 也不可放變數,規定必須為常數值 #### 這裡的break是用來做甚麼的? 如果沒加break,程式會繼續向下一個case執行 :::spoiler Code ```cpp= int a = 1; switch(a){ case 1: std::cout<<"程式"; case 2: std::cout<<"會"; case 3: std::cout<<"走"; case 4: std::cout<<"完"; case 5: std::cout<<"這"; case 6: std::cout<<"些"; case 7: std::cout<<"地"; case 8: std::cout<<"方"; case 9: std::cout<<"才會"; default: std::cout<<"退出"; } ``` ::: #### 所以這到底能用在哪? 用來代替一堆if else :::spoiler Code ```cpp= #include<iostream> int main(){ char a ; std::cin>>a; switch(a){ case '0': std::cout<<'0'; break; case '1': std::cout<<'1'; break; case '2': std::cout<<'2'; break; case '3': std::cout<<'3'; break; case '4': std::cout<<'4'; break; case '5': std::cout<<'5'; break; case '6': std::cout<<'6'; break; case '7': std::cout<<'7'; break; case '8': std::cout<<'8'; break; case '9': std::cout<<'9'; break; default: std::cout<<"Not a number."; break; } } ``` 希望你們不會用到這東西 ::: --- ### if - else if 結構相關 :::spoiler 來源 : ```cpp= if (a){ }else{ if (b){ }else{ if (c){ }else{ if (d){ }else{ } } } } //這和下面的結構是相同的 if (a) else if (b) else if (c) else if(d) else //在經過適當的調整後 if(a) else if(b) else if(c) else if(d) else ``` 沒錯,就是所謂的if - else if結構 ::: #### 到底什麼時候要用大括號? 大括號的功用是圈出一個空間,作為變數的作用域 ```cpp= #include<iostream> int main() { int* pb; //*pb是指標,先知道能和變數存一樣的值就行了 { int b; std::cin >> b; pb = &b; //將pb指定為b,只要b還在或更動pb也會改變 } //從這開始不能使用b,但b並未被刪除 std::cout << *pb; //會輸出b的值 } ``` 而同時,他也會將其中的執行式包含在該作用域之中 if只會執行他下一行的函式或作用域 ```cpp= int a = 1; if (a == 1) std::cout<<"a==1"; else std::cout<<"a!=1"; //這句不會被執行 std::cout<<"這句並不在else裡面,所以會被執行"; ``` 在上面的例子中,第三個cout並不在else裡,但程式碼的縮排會讓人誤認 所以記得在寫程式時依據不同的作用域縮不同的排 ```cpp= int a = 1; if (a == 1) std::cout<<"a==1"; else std::cout<<"a!=1"; //這句不會被執行 std::cout<<"這句並不在else裡面,所以會被執行"; ``` 這樣就很清楚了 那如果要讓它包含在裡面就必須創建新的作用域,並掛在else後面 也就是常見的 ```cpp= if(a == 1){ std::cout<<"a==1"; } else{ std::cout<<"a!=1"; std::cout<<"這句在else裡面,所以不會被執行"; } ``` #### 禁忌 以下是一些容易造成錯誤的用法 1. 在大括號(尤其是if條件判斷中)宣告變數 ```cpp= int a = 1; if(a == 1){ int b = 1; } std::cout << b; //會出現錯誤 //當然,如果只在大括號範圍內使用就沒關係 ``` 2. 在 if/else/else if後加上';' 這是因為C++會以分號來判斷執行式,這樣容易出錯 ```cpp= if(true); std::cout<<"這並不在if裡面"; else //這會出現錯誤,上面會說else找不到if if(true) std::cout<<"目前正常"; else; std::cout<<"這不在else中,所以會被執行"; ``` #### 有關編排的常見方式 程式是寫給人看的,只要能讓人看得懂就沒關係 :::spoiler 1. 全部換行 ```cpp= if(a) { } else { } //這最為工整但也有點占視覺上的空間 ``` ::: :::spoiler 2. 半換行 ```cpp= if(a){ } else{ } ``` ::: :::spoiler 3. 不換行 ```cpp= if(a){ }else{ } //這應該是最常看到的縮排,只是會有點擠 ``` ::: 有關只有一行程式碼的縮排 * 可以考慮省略大括號 ```cpp= if(a%2==0) std::cout<<"a是偶數"; else std::cout<<"a是奇數"; ``` * 如果沒有else,也可以寫在同一行 ```cpp= if(a%2==1) a--; ``` --- ### 三元預算子進階使用 如果你想要在三元運算子裡面多做點事,你可能會需要用到逗號的運算,像這樣 : ```cpp= #include <iostream> using namespace std; int main() { int a; int b = 100; cin >> a; cout << (a%2 ? (b+1, a/2) : (b+2, a+1)) << " " << b << endl; } ``` * 首先,因為逗號運算的關係,雖然命令都有被執行,但是程式的輸出結果會是**後面那一項**。 後面關於逗號運算子會有更詳細的說明,這邊以下面的 Code 來說明 ```cpp= #include <iostream> using namespace std; int main() { int a; int b = 100; cin >> a; cout << (a%2 ? (b+1, a/2) : (b+2, a+1)) << " " << b << endl; //三元運算的部分會輸出 a/2 or a+1,而不是 b+1 or b+2 } ``` * **請注意,逗號運算的優先度低於三元運算子**,所以你如果不括號起來,最後一個命令就不會是在else裡面,而是**一定會執行**。以下面的 Code 來說明 ```cpp= #include <iostream> using namespace std; int main() { int a; int b; cin >> a; cout << (a%2 ? (b = 1, a/2) : b = 2, a+1) << " " << b << endl; //那個a+1一定會執行,因為它不算在三元運算裡面(優先度問題) } ``` 請參閱: [Microsoft Doc](https://docs.microsoft.com/zh-tw/cpp/cpp/conditional-operator-q?view=msvc-160) --- ### 一元運算子 #### 種類 一元運算子的數量並沒有很多,而且大部分都很直覺 * \+ 會回傳參數的值 * \- 會回傳參數的2的補數(負的參數) * ~ 會回傳參數的1的補數(負的參數-1) * ! 會回傳相反的布林值 #### 使用範例 ```cpp= #include<iostream> int main(){ int a = 5; std::cout << +a << ' ' << -a << ' ' << ~a << ' ' << !a; //結果為 5 -5 -6 0 //第四個會是0的原因為5是真,所以相反的是假,也就是0 } ``` --- ### 逗號運算子(Comma operator) 逗號運算子比較特別,他和計算或條件判斷沒什麼關係 它的功用在於將多個執行式結合 #### 基本架構 ```cpp= 執行式1, 執行式2 //當然也可以像下面那樣多加幾個 (執行式1, 執行式2, 執行式3) //通常會用小括號括起來 ``` 會從左到右執行,並回傳最右邊的回傳值 其他的回傳值都會被捨棄,可以用來簡化程式 ###### tags: 要記住不可在逗號運算子內宣告變數,會出現語法錯誤 #### 使用範例 ```cpp= #include<iostream> int main(){ int a; //std::cin>>a; ///std::cout<<a; std::cout << ( std::cin >> a, a); //等同上面註解的部分 //他先將std::cin>>a執行後把回傳的cin丟掉 //再執行a,這動作會回傳a的值,而逗號運算子就會回傳a } ``` 也可以這樣做 ```cpp= #include<iostream> int main(){ int a; //std::cin>>a; //a++; ///std::cout<<a; std::cout << ( std::cin >> a, a++, a); //等同上面註解的部分 //會輸出輸入的數字+1 } ``` 猜猜看會回傳什麼 ```cpp= #include<iostream> int main(){ int a; std::cout << (a = 99, a++, a*100, a+100); } ``` 答案是2\*2\*2\*5\*5,因為在中間的值如果沒被保留下來就會被丟掉 請參閱: [Microsoft Doc](https://docs.microsoft.com/zh-tw/cpp/cpp/comma-operator?view=msvc-160)